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

Commit updating CONNECT from the 10.1 version

This commit is contained in:
Olivier Bertrand
2015-12-04 22:38:16 +01:00
parent dc8a0df0a2
commit 27f9d2f929
50 changed files with 7698 additions and 1022 deletions

View File

@@ -28,8 +28,8 @@ tabvct.cpp tabvir.cpp tabxcl.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp
array.h blkfil.h block.h catalog.h checklvl.h colblk.h connect.h csort.h
engmsg.h filamap.h filamdbf.h filamfix.h filamtxt.h filamvct.h filamzip.h
filter.h global.h ha_connect.h inihandl.h json.h maputil.h msgid.h mycat.h
myconn.h myutil.h os.h osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h
filter.h global.h ha_connect.h inihandl.h json.h jsonudf.h maputil.h msgid.h
mycat.h myconn.h myutil.h os.h osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h
resource.h tabcol.h tabdos.h tabfix.h tabfmt.h tabjson.h tabmul.h tabmysql.h
taboccur.h tabpivot.h tabsys.h tabtbl.h tabutil.h tabvct.h tabvir.h tabxcl.h
user_connect.h valblk.h value.h xindex.h xobject.h xtable.h)
@@ -48,7 +48,7 @@ IF(UNIX)
# Bar: -Wfatal-errors removed (does not present in gcc on solaris10)
if(WITH_WARNINGS)
add_definitions(-Wall -Wextra -Wmissing-declarations)
message(STATUS "CONNECT: GCC: All warnings enabled")
#message(STATUS "CONNECT: GCC: All warnings enabled")
else()
add_definitions(-Wall -Wmissing-declarations)
add_definitions(-Wno-write-strings)
@@ -69,7 +69,7 @@ IF(UNIX)
# These switches are for C++ only
# add_definitions(-Wno-reorder)
message(STATUS "CONNECT: GCC: Some warnings disabled")
#message(STATUS "CONNECT: GCC: Some warnings disabled")
endif(WITH_WARNINGS)
add_definitions( -DUNIX -DLINUX -DUBUNTU )

View File

@@ -735,17 +735,12 @@ static void SetSwapValue(PVAL valp, char *kp)
/* IndexRead: fetch a record having the index value. */
/***********************************************************************/
RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
const void *key, int len, bool mrr)
const key_range *kr, bool mrr)
{
char *kp= (char*)key;
int n, x;
short lg;
bool rcb;
RCODE rc;
PVAL valp;
PCOL colp;
XXBASE *xbp;
PTDBDOX tdbp;
PTDBDOX tdbp;
if (!ptdb)
return RC_FX;
@@ -757,13 +752,13 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
return RC_FX;
} else if (x == 2) {
// Remote index
if (ptdb->ReadKey(g, op, key, len))
if (ptdb->ReadKey(g, op, kr))
return RC_FX;
goto rnd;
} else if (x == 3) {
if (key)
((PTDBASE)ptdb)->SetRecpos(g, *(int*)key);
if (kr)
((PTDBASE)ptdb)->SetRecpos(g, *(int*)kr->key);
if (op == OP_SAME)
return RC_NF;
@@ -790,7 +785,14 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
xbp= (XXBASE*)tdbp->To_Kindex;
if (key) {
if (kr) {
char *kp= (char*)kr->key;
int len= kr->length;
short lg;
bool rcb;
PVAL valp;
PCOL colp;
for (n= 0; n < tdbp->Knum; n++) {
colp= (PCOL)tdbp->To_Key_Col[n];
@@ -832,10 +834,10 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
kp+= valp->GetClen();
if (len == kp - (char*)key) {
if (len == kp - (char*)kr->key) {
n++;
break;
} else if (len < kp - (char*)key) {
} else if (len < kp - (char*)kr->key) {
strcpy(g->Message, "Key buffer is too small");
return RC_FX;
} // endif len

View File

@@ -36,7 +36,7 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp);
int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort);
int CntIndexInit(PGLOBAL g, PTDB tdbp, int id, bool sorted);
RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, bool mrr);
RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const key_range *kr, bool mrr);
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp);
RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp);
RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all);
@@ -60,7 +60,7 @@ class TDBDOX: public TDBDOS {
friend int MakeIndex(PGLOBAL, PTDB, PIXDEF);
friend int CntCloseTable(PGLOBAL, PTDB, bool, bool);
friend int CntIndexInit(PGLOBAL, PTDB, int, bool);
friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const void*, int, bool);
friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const key_range*, bool);
friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool);
friend int CntIndexRange(PGLOBAL, PTDB, const uchar**, uint*,
bool*, key_part_map*);

View File

@@ -1404,8 +1404,13 @@ void ZLBFAM::Rewind(void)
// We must be positioned after the header block
if (CurBlk >= 0) { // Nothing to do if no block read yet
if (!Optimized) { // If optimized, fseek will be done in ReadBuffer
size_t st;
rewind(Stream);
fread(Zlenp, sizeof(int), 1, Stream);
if (!(st = fread(Zlenp, sizeof(int), 1, Stream)) && trace)
htrc("fread error %d in Rewind", errno);
fseek(Stream, *Zlenp + sizeof(int), SEEK_SET);
OldBlk = -1;
} // endif Optimized

View File

@@ -169,9 +169,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
char version[]= "Version 1.03.0007 October 20, 2015";
char version[]= "Version 1.04.0005 November 20, 2015";
#if defined(__WIN__)
char compver[]= "Version 1.03.0007 " __DATE__ " " __TIME__;
char compver[]= "Version 1.04.0005 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
@@ -1114,7 +1114,7 @@ int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef)
else if (!stricmp(opname, "Compressed"))
opval= (options->compressed);
if (opval == NO_IVAL) {
if (opval == (ulonglong)NO_IVAL) {
char *pv;
if ((pv= GetListOption(g, opname, options->oplist)))
@@ -1135,9 +1135,9 @@ PTOS ha_connect::GetTableOptionStruct(TABLE_SHARE *s)
TABLE_SHARE *tsp= (tshp) ? tshp : (s) ? s : table_share;
return (tsp && (!tsp->db_plugin ||
!stricmp(plugin_name(tsp->db_plugin)->str, "connect") ||
!stricmp(plugin_name(tsp->db_plugin)->str, "partition")))
? tsp->option_struct : NULL;
!stricmp(plugin_name(tsp->db_plugin)->str, "connect") ||
!stricmp(plugin_name(tsp->db_plugin)->str, "partition")))
? tsp->option_struct : NULL;
} // end of GetTableOptionStruct
/****************************************************************************/
@@ -2191,99 +2191,159 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *)
/***********************************************************************/
int ha_connect::CheckRecord(PGLOBAL g, const uchar *, uchar *newbuf)
{
return ScanRecord(g, newbuf);
return ScanRecord(g, newbuf);
} // end of dummy CheckRecord
/***********************************************************************/
/* Return true if this field is used in current indexing. */
/***********************************************************************/
bool ha_connect::IsIndexed(Field *fp)
{
if (active_index < MAX_KEY) {
KEY_PART_INFO *kpart;
KEY *kfp= &table->key_info[active_index];
uint rem= kfp->user_defined_key_parts;
for (kpart= kfp->key_part; rem; rem--, kpart++)
if (kpart->field == fp)
return true;
} // endif active_index
return false;
} // end of IsIndexed
/***********************************************************************/
/* Return the where clause for remote indexed read. */
/***********************************************************************/
bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL op, char q,
const void *key, int klen)
bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
const key_range *kr)
{
const uchar *ptr;
uint rem, len, stlen; //, prtlen;
bool nq, oom, b= false;
Field *fp;
KEY *kfp;
KEY_PART_INFO *kpart;
const uchar *ptr;
//uint i, rem, len, klen, stlen;
uint i, rem, len, stlen;
bool nq, both, oom= false;
OPVAL op;
Field *fp;
const key_range *ranges[2];
my_bitmap_map *old_map;
KEY *kfp;
KEY_PART_INFO *kpart;
if (active_index == MAX_KEY)
return false;
else if (!key) {
strcpy(g->Message, "MakeKeyWhere: No key");
return true;
} // endif key
oom= qry->Append(" WHERE (");
kfp= &table->key_info[active_index];
rem= kfp->user_defined_key_parts,
len= klen,
ptr= (const uchar *)key;
ranges[0]= kr;
ranges[1]= (end_range && !eq_range) ? &save_end_range : NULL;
for (kpart= kfp->key_part; rem; rem--, kpart++) {
fp= kpart->field;
stlen= kpart->store_length;
// prtlen= MY_MIN(stlen, len);
nq= fp->str_needs_quotes();
if (!ranges[0] && !ranges[1]) {
strcpy(g->Message, "MakeKeyWhere: No key");
return true;
} else
both= ranges[0] && ranges[1];
if (b)
oom|= qry->Append(" AND ");
else
b= true;
kfp= &table->key_info[active_index];
old_map= dbug_tmp_use_all_columns(table, table->write_set);
oom|= qry->Append(q);
oom|= qry->Append((PSZ)fp->field_name);
oom|= qry->Append(q);
for (i = 0; i <= 1; i++) {
if (ranges[i] == NULL)
continue;
switch (op) {
case OP_EQ:
case OP_GT:
case OP_GE:
case OP_LT:
case OP_LE:
oom |= qry->Append((PSZ)GetValStr(op, false));
break;
default:
oom|= qry->Append(" ??? ");
} // endwitch op
if (both && i > 0)
oom|= qry->Append(") AND (");
else
oom|= qry->Append(" WHERE (");
if (nq)
oom|= qry->Append('\'');
// klen= len= ranges[i]->length;
len= ranges[i]->length;
rem= kfp->user_defined_key_parts;
ptr= ranges[i]->key;
if (kpart->key_part_flag & HA_VAR_LENGTH_PART) {
String varchar;
uint var_length= uint2korr(ptr);
for (kpart= kfp->key_part; rem; rem--, kpart++) {
fp= kpart->field;
stlen= kpart->store_length;
nq= fp->str_needs_quotes();
varchar.set_quick((char*) ptr+HA_KEY_BLOB_LENGTH,
var_length, &my_charset_bin);
oom|= qry->Append(varchar.ptr(), varchar.length());
} else {
char strbuff[MAX_FIELD_WIDTH];
String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res;
if (kpart != kfp->key_part)
oom|= qry->Append(" AND ");
res= fp->val_str(&str, ptr);
oom|= qry->Append(res->ptr(), res->length());
} // endif flag
if (q) {
oom|= qry->Append(q);
oom|= qry->Append((PSZ)fp->field_name);
oom|= qry->Append(q);
} else
oom|= qry->Append((PSZ)fp->field_name);
if (nq)
oom|= qry->Append('\'');
switch (ranges[i]->flag) {
case HA_READ_KEY_EXACT:
// op= (stlen >= len || !nq || fp->result_type() != STRING_RESULT)
// ? OP_EQ : OP_LIKE;
op= OP_EQ;
break;
case HA_READ_AFTER_KEY:
op= (stlen >= len) ? (!i ? OP_GT : OP_LE) : OP_GE;
break;
case HA_READ_KEY_OR_NEXT:
op= OP_GE;
break;
case HA_READ_BEFORE_KEY:
op= (stlen >= len) ? OP_LT : OP_LE;
break;
case HA_READ_KEY_OR_PREV:
op= OP_LE;
break;
default:
sprintf(g->Message, "cannot handle flag %d", ranges[i]->flag);
goto err;
} // endswitch flag
if (stlen >= len)
break;
oom|= qry->Append((PSZ)GetValStr(op, false));
len-= stlen;
if (nq)
oom|= qry->Append('\'');
/* For nullable columns, null-byte is already skipped before, that is
ptr was incremented by 1. Since store_length still counts null-byte,
we need to subtract 1 from store_length. */
ptr+= stlen - MY_TEST(kpart->null_bit);
} // endfor kpart
if (kpart->key_part_flag & HA_VAR_LENGTH_PART) {
String varchar;
uint var_length= uint2korr(ptr);
varchar.set_quick((char*)ptr + HA_KEY_BLOB_LENGTH,
var_length, &my_charset_bin);
oom|= qry->Append(varchar.ptr(), varchar.length(), nq);
} else {
char strbuff[MAX_FIELD_WIDTH];
String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res;
res= fp->val_str(&str, ptr);
oom|= qry->Append(res->ptr(), res->length(), nq);
} // endif flag
if (nq)
oom |= qry->Append('\'');
if (stlen >= len)
break;
len-= stlen;
/* For nullable columns, null-byte is already skipped before, that is
ptr was incremented by 1. Since store_length still counts null-byte,
we need to subtract 1 from store_length. */
ptr+= stlen - MY_TEST(kpart->null_bit);
} // endfor kpart
} // endfor i
if ((oom|= qry->Append(")")))
strcpy(g->Message, "Out of memory");
return oom;
dbug_tmp_restore_column_map(table->write_set, old_map);
return oom;
err:
dbug_tmp_restore_column_map(table->write_set, old_map);
return true;
} // end of MakeKeyWhere
@@ -2483,9 +2543,11 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_NEWDATE:
return NULL;
default:
break;
} // endswitch type
if (trace) {
if (trace) {
htrc("Field index=%d\n", pField->field->field_index);
htrc("Field name=%s\n", pField->field->field_name);
} // endif trace
@@ -2562,8 +2624,9 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
/***********************************************************************/
/* Check the WHERE condition and return a MYSQL/ODBC/WQL filter. */
/***********************************************************************/
PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
{
AMT tty = filp->Type;
char *body= filp->Body;
unsigned int i;
bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
@@ -2596,7 +2659,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
List<Item>* arglist= cond_item->argument_list();
List_iterator<Item> li(*arglist);
Item *subitem;
const Item *subitem;
p1= body + strlen(body);
strcpy(p1, "(");
@@ -2604,7 +2667,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
for (i= 0; i < arglist->elements; i++)
if ((subitem= li++)) {
if (!CheckCond(g, filp, tty, subitem)) {
if (!CheckCond(g, filp, subitem)) {
if (vop == OP_OR || nonul)
return NULL;
else
@@ -2626,26 +2689,27 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
} else if (cond->type() == COND::FUNC_ITEM) {
unsigned int i;
// int n;
bool iscol, neg= FALSE;
Item_func *condf= (Item_func *)cond;
Item* *args= condf->arguments();
if (trace)
htrc("Func type=%d argnum=%d\n", condf->functype(),
condf->argument_count());
// neg= condf->
condf->argument_count());
switch (condf->functype()) {
case Item_func::EQUAL_FUNC:
case Item_func::EQ_FUNC: vop= OP_EQ; break;
case Item_func::NE_FUNC: vop= OP_NE; break;
case Item_func::LT_FUNC: vop= OP_LT; break;
case Item_func::LE_FUNC: vop= OP_LE; break;
case Item_func::GE_FUNC: vop= OP_GE; break;
case Item_func::GT_FUNC: vop= OP_GT; break;
case Item_func::IN_FUNC: vop= OP_IN;
case Item_func::EQ_FUNC: vop= OP_EQ; break;
case Item_func::NE_FUNC: vop= OP_NE; break;
case Item_func::LT_FUNC: vop= OP_LT; break;
case Item_func::LE_FUNC: vop= OP_LE; break;
case Item_func::GE_FUNC: vop= OP_GE; break;
case Item_func::GT_FUNC: vop= OP_GT; break;
case Item_func::LIKE_FUNC: vop= OP_LIKE; break;
case Item_func::ISNOTNULL_FUNC:
neg = true;
case Item_func::ISNULL_FUNC: vop= OP_NULL; break;
case Item_func::IN_FUNC: vop= OP_IN;
case Item_func::BETWEEN:
ismul= true;
neg= ((Item_func_opt_neg *)condf)->negated;
@@ -2658,7 +2722,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
else if (ismul && tty == TYPE_AM_WMI)
return NULL; // Not supported by WQL
if (x && (neg || !(vop == OP_EQ || vop == OP_IN)))
if (x && (neg || !(vop == OP_EQ || vop == OP_IN || vop == OP_NULL)))
return NULL;
for (i= 0; i < condf->argument_count(); i++) {
@@ -2679,9 +2743,10 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if (x && i)
return NULL;
if (pField->field->table != table)
return NULL; // Field does not belong to this table
else if (pField->field->table != table)
return NULL; // Field does not belong to this table
else if (tty != TYPE_AM_WMI && IsIndexed(pField->field))
return NULL; // Will be handled by ReadKey
else
fop= GetFieldOptionStruct(pField->field);
@@ -2712,7 +2777,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
strcat(body, fnm);
} else if (args[i]->type() == COND::FUNC_ITEM) {
if (tty == TYPE_AM_MYSQL) {
if (!CheckCond(g, filp, tty, args[i]))
if (!CheckCond(g, filp, args[i]))
return NULL;
} else
@@ -2901,14 +2966,17 @@ const COND *ha_connect::cond_push(const COND *cond)
goto fin;
if (b) {
PCFIL filp= (PCFIL)PlugSubAlloc(g, NULL, sizeof(CONDFIL));
PCFIL filp;
if ((filp= tdbp->GetCondFil()) && filp->Cond == cond &&
filp->Idx == active_index && filp->Type == tty)
goto fin; // Already done
filp= new(g) CONDFIL(cond, active_index, tty);
filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
*filp->Body= 0;
filp->Op= OP_XX;
filp->Cmds= NULL;
if (CheckCond(g, filp, tty, (Item *)cond)) {
if (CheckCond(g, filp, cond)) {
if (trace)
htrc("cond_push: %s\n", filp->Body);
@@ -3372,13 +3440,13 @@ int ha_connect::index_end()
/****************************************************************************/
/* This is internally called by all indexed reading functions. */
/****************************************************************************/
int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const uchar *key, uint key_len)
int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const key_range *kr)
{
int rc;
//statistic_increment(ha_read_key_count, &LOCK_status);
switch (CntIndexRead(xp->g, tdbp, op, key, (int)key_len, mrr)) {
switch (CntIndexRead(xp->g, tdbp, op, kr, mrr)) {
case RC_OK:
xp->fnd++;
rc= MakeRecord((char*)buf);
@@ -3444,7 +3512,12 @@ int ha_connect::index_read(uchar * buf, const uchar * key, uint key_len,
htrc("%p index_read: op=%d\n", this, op);
if (indexing > 0) {
rc= ReadIndexed(buf, op, key, key_len);
start_key.key= key;
start_key.length= key_len;
start_key.flag= find_flag;
start_key.keypart_map= 0;
rc= ReadIndexed(buf, op, &start_key);
if (rc == HA_ERR_INTERNAL_ERROR) {
nox= true; // To block making indexes
@@ -3750,7 +3823,7 @@ void ha_connect::position(const uchar *)
//if (((PTDBASE)tdbp)->GetDef()->Indexable())
my_store_ptr(ref, ref_length, (my_off_t)((PTDBASE)tdbp)->GetRecpos());
if (trace)
if (trace > 1)
htrc("position: pos=%d\n", ((PTDBASE)tdbp)->GetRecpos());
DBUG_VOID_RETURN;
@@ -4034,7 +4107,27 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
case TAB_MAC:
case TAB_WMI:
case TAB_OEM:
return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
#ifdef NO_EMBEDDED_ACCESS_CHECKS
return false;
#endif
/*
If table or table->mdl_ticket is NULL - it's a DLL, e.g. CREATE TABLE.
if the table has an MDL_EXCLUSIVE lock - it's a DDL too, e.g. the
insert step of CREATE ... SELECT.
Otherwise it's a DML, the table was normally opened, locked,
privilege were already checked, and table->grant.privilege is set.
With SQL SECURITY DEFINER, table->grant.privilege has definer's privileges.
*/
if (!table || !table->mdl_ticket || table->mdl_ticket->get_type() == MDL_EXCLUSIVE)
return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
if (table->grant.privilege & FILE_ACL)
return false;
status_var_increment(thd->status_var.access_denied_errors);
my_error(access_denied_error_code(thd->password), MYF(0),
thd->security_ctx->priv_user, thd->security_ctx->priv_host,
(thd->password ? ER(ER_YES) : ER(ER_NO)));
return true;
// This is temporary until a solution is found
case TAB_TBL:
@@ -4421,15 +4514,16 @@ int ha_connect::external_lock(THD *thd, int lock_type)
xmod= MODE_ANY; // For info commands
DBUG_RETURN(rc);
} // endif MODE_ANY
DBUG_ASSERT(table && table->s);
else
if (check_privileges(thd, options, table->s->db.str)) {
strcpy(g->Message, "This operation requires the FILE privilege");
htrc("%s\n", g->Message);
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif check_privileges
DBUG_ASSERT(table && table->s);
// Table mode depends on the query type
newmode= CheckMode(g, thd, newmode, &xcheck, &cras);
@@ -5068,7 +5162,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
hdr= (int)topt->header;
tbl= topt->tablist;
col= topt->colist;
lrecl= (int)topt->lrecl;
if (topt->oplist) {
host= GetListOption(g, "host", topt->oplist, "localhost");
@@ -5684,6 +5777,14 @@ int ha_connect::create(const char *name, TABLE *table_arg,
PGLOBAL g= xp->g;
DBUG_ENTER("ha_connect::create");
/*
This assignment fixes test failures if some
"ALTER TABLE t1 ADD KEY(a)" query exits on ER_ACCESS_DENIED_ERROR
(e.g. on missing FILE_ACL). All following "CREATE TABLE" failed with
"ERROR 1105: CONNECT index modification should be in-place"
TODO: check with Olivier.
*/
g->Xchk= NULL;
int sqlcom= thd_sql_command(table_arg->in_use);
PTOS options= GetTableOptionStruct(table_arg->s);
@@ -6173,10 +6274,6 @@ bool ha_connect::FileExists(const char *fn, bool bf)
int n;
struct stat info;
if (check_access(ha_thd(), FILE_ACL, table->s->db.str,
NULL, NULL, 0, 0))
return true;
#if defined(__WIN__)
s= "\\";
#else // !__WIN__
@@ -6662,10 +6759,10 @@ maria_declare_plugin(connect)
PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */
0x0103, /* version number (1.03) */
0x0104, /* version number (1.04) */
NULL, /* status variables */
connect_system_variables, /* system variables */
"1.03.0007", /* string version */
MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
"1.04.0003", /* string version */
MariaDB_PLUGIN_MATURITY_BETA /* maturity */
}
maria_declare_plugin_end;

View File

@@ -241,11 +241,12 @@ public:
int MakeRecord(char *buf);
int ScanRecord(PGLOBAL g, uchar *buf);
int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL,
uint key_len= 0);
int ReadIndexed(uchar *buf, OPVAL op, const key_range *kr= NULL);
bool IsIndexed(Field *fp);
bool MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL op, char q,
const void *key, int klen);
const key_range *kr);
inline char *Strz(LEX_STRING &ls);
key_range start_key;
/** @brief
@@ -374,7 +375,7 @@ public:
condition stack.
*/
virtual const COND *cond_push(const COND *cond);
PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond);
PCFIL CheckCond(PGLOBAL g, PCFIL filp, const Item *cond);
const char *GetValStr(OPVAL vop, bool neg);
PFIL CondFilter(PGLOBAL g, Item *cond);
//PFIL CheckFilter(PGLOBAL g);

View File

@@ -1,5 +1,5 @@
/*************** json CPP Declares Source Code File (.H) ***************/
/* Name: json.cpp Version 1.1 */
/* Name: json.cpp Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
/* */
@@ -31,11 +31,12 @@
/***********************************************************************/
/* Parse a json string. */
/* Note: when pretty is not known, the caller set pretty to 3. */
/***********************************************************************/
PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
{
int i, rc;
bool b = false;
int i, rc, pretty = (ptyp) ? *ptyp : 3;
bool b = false, pty[3] = {true, true, true};
PJSON jsp = NULL;
STRG src;
@@ -48,6 +49,10 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
src.str = s;
src.len = len;
// Trying to guess the pretty format
if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n')))
pty[0] = false;
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
@@ -58,21 +63,19 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
goto err;
} // endif rc
for (i = 0; i < len; i++)
for (i = 0; i < len; i++)
switch (s[i]) {
case '[':
if (jsp) {
strcpy(g->Message, "More than one item in file");
goto err;
} else if (!(jsp = ParseArray(g, ++i, src)))
if (jsp)
goto tryit;
else if (!(jsp = ParseArray(g, ++i, src, pty)))
goto err;
break;
case '{':
if (jsp) {
strcpy(g->Message, "More than one item in file");
goto err;
} else if (!(jsp = ParseObject(g, ++i, src)))
if (jsp)
goto tryit;
else if (!(jsp = ParseObject(g, ++i, src, pty)))
goto err;
break;
@@ -82,20 +85,16 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
case '\r':
break;
case ',':
if (jsp && pretty == 1) {
if (jsp && (pretty == 1 || pretty == 3)) {
if (comma)
*comma = true;
pty[0] = pty[2] = false;
break;
} // endif pretty
sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty);
goto err;
case '"':
if (!(jsp = ParseValue(g, i, src)))
goto err;
break;
case '(':
b = true;
break;
@@ -106,18 +105,41 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
} // endif b
default:
sprintf(g->Message, "Bad '%c' character near %.*s",
s[i], ARGS);
goto err;
}; // endswitch s[i]
if (jsp)
goto tryit;
else if (!(jsp = ParseValue(g, i, src, pty)))
goto err;
if (!jsp)
sprintf(g->Message, "Invalid Json string '%.*s'", 50, s);
break;
}; // endswitch s[i]
if (!jsp)
sprintf(g->Message, "Invalid Json string '%.*s'", 50, s);
else if (ptyp && pretty == 3) {
*ptyp = 3; // Not recognized pretty
for (i = 0; i < 3; i++)
if (pty[i]) {
*ptyp = i;
break;
} // endif pty
} // endif ptyp
g->jump_level--;
return jsp;
err:
tryit:
if (pty[0] && (!pretty || pretty > 2)) {
if ((jsp = ParseArray(g, (i = 0), src, pty)) && ptyp && pretty == 3)
*ptyp = (pty[0]) ? 0 : 3;
g->jump_level--;
return jsp;
} else
strcpy(g->Message, "More than one item in file");
err:
g->jump_level--;
return NULL;
} // end of ParseJson
@@ -125,11 +147,12 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
/***********************************************************************/
/* Parse a JSON Array. */
/***********************************************************************/
PJAR ParseArray(PGLOBAL g, int& i, STRG& src)
PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty)
{
char *s = src.str;
int len = src.len;
int level = 0;
bool b = (!i);
PJAR jarp = new(g) JARRAY;
PJVAL jvp = NULL;
@@ -151,25 +174,32 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src)
jarp->InitArray(g);
return jarp;
case ' ':
case '\n':
if (!b)
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
if (level == 2) {
sprintf(g->Message, "Unexpected value near %.*s", ARGS);
return NULL;
} else if ((jvp = ParseValue(g, i, src))) {
} else if ((jvp = ParseValue(g, i, src, pty)))
jarp->AddValue(g, jvp);
level = 2;
} else
else
return NULL;
level = 2;
level = (b) ? 1 : 2;
break;
}; // endswitch s[i]
if (b) {
// Case of Pretty == 0
jarp->InitArray(g);
return jarp;
} // endif b
strcpy(g->Message, "Unexpected EOF in array");
return NULL;
} // end of ParseArray
@@ -177,7 +207,7 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/
/* Parse a JSON Object. */
/***********************************************************************/
PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty)
{
PSZ key;
char *s = src.str;
@@ -204,7 +234,7 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
break;
case ':':
if (level == 1) {
if (!(jpp->Val = ParseValue(g, ++i, src)))
if (!(jpp->Val = ParseValue(g, ++i, src, pty)))
return NULL;
level = 2;
@@ -229,10 +259,11 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
} // endif level
return jobp;
case ' ':
case '\n':
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
sprintf(g->Message, "Unexpected character '%c' near %.*s",
@@ -247,7 +278,7 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/
/* Parse a JSON Value. */
/***********************************************************************/
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty)
{
char *strval, *s = src.str;
int n, len = src.len;
@@ -255,10 +286,11 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
for (; i < len; i++)
switch (s[i]) {
case ' ':
case '\n':
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
goto suite;
@@ -267,12 +299,12 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
suite:
switch (s[i]) {
case '[':
if (!(jvp->Jsp = ParseArray(g, ++i, src)))
if (!(jvp->Jsp = ParseArray(g, ++i, src, pty)))
return NULL;
break;
case '{':
if (!(jvp->Jsp = ParseObject(g, ++i, src)))
if (!(jvp->Jsp = ParseObject(g, ++i, src, pty)))
return NULL;
break;
@@ -319,7 +351,6 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
}; // endswitch s[i]
jvp->Size = 1;
return jvp;
err:
@@ -481,9 +512,9 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
valp = AllocateValue(g, &dv, TYPE_DOUBLE, nd);
} else {
int iv = strtol(buf, NULL, 10);
long long iv = strtoll(buf, NULL, 10);
valp = AllocateValue(g, &iv, TYPE_INT);
valp = AllocateValue(g, &iv, TYPE_BIGINT);
} // endif has
i--; // Unstack following character
@@ -501,35 +532,44 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/
/* Serialize a JSON tree: */
/***********************************************************************/
PSZ Serialize(PGLOBAL g, PJSON jsp, FILE *fs, int pretty)
PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty)
{
bool b = false, err = true;
JOUT *jp;
FILE *fs = NULL;
g->Message[0] = 0;
g->Message[0] = 0;
if (!jsp) {
strcpy(g->Message, "Null json tree");
return NULL;
} else if (!fs) {
} else if (!fn) {
// Serialize to a string
jp = new(g) JOUTSTR(g);
b = pretty == 1;
} else if (pretty == 2) {
// Serialize to a pretty file
jp = new(g) JOUTPRT(g, fs);
} else {
// Serialize to a flat file
jp = new(g) JOUTFILE(g, fs);
b = pretty == 1;
} // endif's
} else {
if (!(fs = fopen(fn, "wb"))) {
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"w", (int)errno, fn);
strcat(strcat(g->Message, ": "), strerror(errno));
return g->Message;
} else if (pretty >= 2) {
// Serialize to a pretty file
jp = new(g)JOUTPRT(g, fs);
} else {
// Serialize to a flat file
b = true;
jp = new(g)JOUTFILE(g, fs, pretty);
} // endif's
} // endif's
switch (jsp->GetType()) {
case TYPE_JAR:
err = SerializeArray(jp, (PJAR)jsp, b);
break;
case TYPE_JOB:
err = (b && jp->WriteChr('\t'));
err = ((b && jp->Prty()) && jp->WriteChr('\t'));
err |= SerializeObject(jp, (PJOB)jsp);
break;
case TYPE_JVAL:
@@ -540,7 +580,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, FILE *fs, int pretty)
} // endswitch Type
if (fs) {
fputc('\n', fs);
fputs(EL, fs);
fclose(fs);
return (err) ? g->Message : NULL;
} else if (!err) {
@@ -565,29 +605,40 @@ bool SerializeArray(JOUT *js, PJAR jarp, bool b)
{
bool first = true;
if (b) {
if (js->Prty()) {
if (js->WriteChr('['))
return true;
else if (js->Prty() == 1 && (js->WriteStr(EL) || js->WriteChr('\t')))
return true;
if (js->WriteChr('['))
return true;
else if (b && (js->WriteStr(EL) || js->WriteChr('\t')))
return true;
} // endif Prty
} else if (js->WriteChr('['))
return true;
for (int i = 0; i < jarp->size(); i++) {
if (first)
first = false;
else if (js->WriteChr(','))
return true;
else if (b && (js->WriteStr(EL) || js->WriteChr('\t')))
else if ((!b || js->Prty()) && js->WriteChr(','))
return true;
else if (b) {
if (js->Prty() < 2 && js->WriteStr(EL))
return true;
else if (js->Prty() == 1 && js->WriteChr('\t'))
return true;
} // endif b
if (SerializeValue(js, jarp->GetValue(i)))
return true;
} // endfor i
if (b && js->WriteStr(EL))
if (b && js->Prty() == 1 && js->WriteStr(EL))
return true;
return js->WriteChr(']');
return ((!b || js->Prty()) && js->WriteChr(']'));
} // end of SerializeArray
/***********************************************************************/
@@ -647,8 +698,8 @@ bool SerializeValue(JOUT *js, PJVAL jvp)
} // endswitch Type
strcpy(js->g->Message, "Unrecognized value");
return true;
strcpy(js->g->Message, "Unrecognized value");
return true;
} // end of SerializeValue
/* -------------------------- Class JOUTSTR -------------------------- */
@@ -866,6 +917,20 @@ PJPR JOBJECT::AddPair(PGLOBAL g, PSZ key)
return jpp;
} // end of AddPair
/***********************************************************************/
/* Return all keys as an array. */
/***********************************************************************/
PJAR JOBJECT::GetKeyList(PGLOBAL g)
{
PJAR jarp = new(g) JARRAY();
for (PJPR jpp = First; jpp; jpp = jpp->Next)
jarp->AddValue(g, new(g) JVALUE(g, jpp->GetKey()));
jarp->InitArray(g);
return jarp;
} // end of GetKeyList
/***********************************************************************/
/* Get the value corresponding to the given key. */
/***********************************************************************/
@@ -903,12 +968,30 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
return text + n;
} // end of GetValue;
/***********************************************************************/
/* Merge two objects. */
/***********************************************************************/
bool JOBJECT::Merge(PGLOBAL g, PJSON jsp)
{
if (jsp->GetType() != TYPE_JOB) {
strcpy(g->Message, "Second argument is not an object");
return true;
} // endif Type
PJOB jobp = (PJOB)jsp;
for (PJPR jpp = jobp->First; jpp; jpp = jpp->Next)
SetValue(g, jpp->GetVal(), jpp->GetKey());
return false;
} // end of Marge;
/***********************************************************************/
/* Set or add a value corresponding to the given key. */
/***********************************************************************/
void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key)
{
PJPR jp;
PJPR jp;
for (jp = First; jp; jp = jp->Next)
if (!strcmp(jp->Key, key)) {
@@ -923,6 +1006,23 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key)
} // end of SetValue
/***********************************************************************/
/* Delete a value corresponding to the given key. */
/***********************************************************************/
void JOBJECT::DeleteKey(PSZ key)
{
PJPR jp, *pjp = &First;
for (jp = First; jp; jp = jp->Next)
if (!strcmp(jp->Key, key)) {
*pjp = jp->Next;
Size--;
break;
} else
pjp = &jp->Next;
} // end of DeleteKey
/***********************************************************************/
/* True if void or if all members are nulls. */
/***********************************************************************/
@@ -943,23 +1043,25 @@ bool JOBJECT::IsNull(void)
void JARRAY::InitArray(PGLOBAL g)
{
int i;
PJVAL jvp;
PJVAL jvp, *pjvp = &First;
for (Size = 0, jvp = First; jvp; jvp = jvp->Next)
if (!jvp->Del)
Size++;
if (!Size) {
return;
} else if (Size > Alloc) {
if (Size > Alloc) {
// No need to realloc after deleting values
Mvals = (PJVAL*)PlugSubAlloc(g, NULL, Size * sizeof(PJVAL));
Alloc = Size;
} // endif Size
for (i = 0, jvp = First; jvp; jvp = jvp->Next)
if (!jvp->Del)
Mvals[i++] = jvp;
if (!jvp->Del) {
Mvals[i++] = jvp;
pjvp = &jvp->Next;
Last = jvp;
} else
*pjvp = jvp->Next;
} // end of InitArray
@@ -975,31 +1077,66 @@ PJVAL JARRAY::GetValue(int i)
} // end of GetValue
/***********************************************************************/
/* Add a Value to the Arrays Value list. */
/* Add a Value to the Array Value list. */
/***********************************************************************/
PJVAL JARRAY::AddValue(PGLOBAL g, PJVAL jvp)
PJVAL JARRAY::AddValue(PGLOBAL g, PJVAL jvp, int *x)
{
if (!jvp)
jvp = new(g) JVALUE;
if (Last)
Last->Next = jvp;
else
First = jvp;
if (x) {
int i = 0, n = *x;
PJVAL jp, *jpp = &First;
for (jp = First; jp && i < n; i++, jp = *(jpp = &jp->Next));
(*jpp) = jvp;
if (!(jvp->Next = jp))
Last = jvp;
} else {
if (!First)
First = jvp;
else if (Last == First)
First->Next = Last = jvp;
else
Last->Next = jvp;
Last = jvp;
} // endif x
Last = jvp;
return jvp;
} // end of AddValue
/***********************************************************************/
/* Add a Value to the Arrays Value list. */
/* Merge two arrays. */
/***********************************************************************/
bool JARRAY::Merge(PGLOBAL g, PJSON jsp)
{
if (jsp->GetType() != TYPE_JAR) {
strcpy(g->Message, "Second argument is not an array");
return true;
} // endif Type
PJAR arp = (PJAR)jsp;
for (int i = 0; i < jsp->size(); i++)
AddValue(g, arp->GetValue(i));
InitArray(g);
return false;
} // end of Merge
/***********************************************************************/
/* Set the nth Value of the Array Value list. */
/***********************************************************************/
bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n)
{
int i = 0;
PJVAL jp, *jpp = &First;
for (i = 0, jp = First; i < n; i++, jp = *(jpp = &jp->Next))
for (jp = First; i < n; i++, jp = *(jpp = &jp->Next))
if (!jp)
*jpp = jp = new(g) JVALUE;
@@ -1048,6 +1185,17 @@ JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON()
Del = false;
} // end of JVALUE constructor
/***********************************************************************/
/* Constructor for a given string. */
/***********************************************************************/
JVALUE::JVALUE(PGLOBAL g, PSZ strp) : JSON()
{
Jsp = NULL;
Value = AllocateValue(g, strp, TYPE_STRING);
Next = NULL;
Del = false;
} // end of JVALUE constructor
/***********************************************************************/
/* Returns the type of the Value's value. */
/***********************************************************************/
@@ -1092,6 +1240,14 @@ int JVALUE::GetInteger(void)
return (Value) ? Value->GetIntValue() : 0;
} // end of GetInteger
/***********************************************************************/
/* Return the Value's Big integer value. */
/***********************************************************************/
long long JVALUE::GetBigint(void)
{
return (Value) ? Value->GetBigintValue() : 0;
} // end of GetBigint
/***********************************************************************/
/* Return the Value's Double value. */
/***********************************************************************/
@@ -1128,13 +1284,44 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
return text;
} // end of GetText
void JVALUE::SetValue(PJSON jsp)
{
if (jsp && jsp->GetType() == TYPE_JVAL) {
Jsp = jsp->GetJsp();
Value = jsp->GetValue();
} else {
Jsp = jsp;
Value = NULL;
} // endif Type
} // end of SetValue;
/***********************************************************************/
/* Set the Value's value as the given integer. */
/***********************************************************************/
void JVALUE::SetInteger(PGLOBAL g, int n)
{
Value = AllocateValue(g, &n, TYPE_INT);
} // end of AddInteger
Jsp = NULL;
} // end of SetInteger
/***********************************************************************/
/* Set the Value's Boolean value as a tiny integer. */
/***********************************************************************/
void JVALUE::SetTiny(PGLOBAL g, char n)
{
Value = AllocateValue(g, &n, TYPE_TINY);
Jsp = NULL;
} // end of SetInteger
/***********************************************************************/
/* Set the Value's value as the given big integer. */
/***********************************************************************/
void JVALUE::SetBigint(PGLOBAL g, long long ll)
{
Value = AllocateValue(g, &ll, TYPE_BIGINT);
Jsp = NULL;
} // end of SetBigint
/***********************************************************************/
/* Set the Value's value as the given DOUBLE. */
@@ -1142,15 +1329,17 @@ void JVALUE::SetInteger(PGLOBAL g, int n)
void JVALUE::SetFloat(PGLOBAL g, double f)
{
Value = AllocateValue(g, &f, TYPE_DOUBLE, 6);
} // end of AddFloat
Jsp = NULL;
} // end of SetFloat
/***********************************************************************/
/* Set the Value's value as the given string. */
/***********************************************************************/
void JVALUE::SetString(PGLOBAL g, PSZ s)
void JVALUE::SetString(PGLOBAL g, PSZ s, short c)
{
Value = AllocateValue(g, s, TYPE_STRING);
} // end of AddFloat
Value = AllocateValue(g, s, TYPE_STRING, c);
Jsp = NULL;
} // end of SetString
/***********************************************************************/
/* True when its JSON or normal value is null. */

View File

@@ -1,5 +1,5 @@
/**************** json H Declares Source Code File (.H) ****************/
/* Name: json.h Version 1.1 */
/* Name: json.h Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
/* */
@@ -16,8 +16,9 @@
enum JTYP {TYPE_STRG = 1,
TYPE_DBL = 2,
TYPE_BOOL = 4,
TYPE_INTG = 7,
TYPE_JSON = 12,
TYPE_BINT = 5,
TYPE_INTG = 7,
TYPE_JSON = 12,
TYPE_JAR,
TYPE_JOB,
TYPE_JVAL};
@@ -40,13 +41,13 @@ typedef struct {
int len;
} STRG, *PSG;
PJSON ParseJson(PGLOBAL g, char *s, int n, int prty, bool *b = NULL);
PJAR ParseArray(PGLOBAL g, int& i, STRG& src);
PJOB ParseObject(PGLOBAL g, int& i, STRG& src);
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src);
PJSON ParseJson(PGLOBAL g, char *s, int n, int *prty = NULL, bool *b = NULL);
PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty);
PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty);
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty);
char *ParseString(PGLOBAL g, int& i, STRG& src);
PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src);
PSZ Serialize(PGLOBAL g, PJSON jsp, FILE *fs, int pretty);
PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty);
bool SerializeArray(JOUT *js, PJAR jarp, bool b);
bool SerializeObject(JOUT *js, PJOB jobp);
bool SerializeValue(JOUT *js, PJVAL jvp);
@@ -56,14 +57,16 @@ bool SerializeValue(JOUT *js, PJVAL jvp);
/***********************************************************************/
class JOUT : public BLOCK {
public:
JOUT(PGLOBAL gp) : BLOCK() {g = gp;}
JOUT(PGLOBAL gp) : BLOCK() {g = gp; Pretty = 3;}
virtual bool WriteStr(const char *s) = 0;
virtual bool WriteChr(const char c) = 0;
virtual bool Escape(const char *s) = 0;
int Prty(void) {return Pretty;}
// Member
PGLOBAL g;
int Pretty;
}; // end of class JOUT
/***********************************************************************/
@@ -88,7 +91,7 @@ class JOUTSTR : public JOUT {
/***********************************************************************/
class JOUTFILE : public JOUT {
public:
JOUTFILE(PGLOBAL g, FILE *str) : JOUT(g) {Stream = str;}
JOUTFILE(PGLOBAL g, FILE *str, int pty) : JOUT(g) {Stream = str; Pretty = pty;}
virtual bool WriteStr(const char *s);
virtual bool WriteChr(const char c);
@@ -103,7 +106,7 @@ class JOUTFILE : public JOUT {
/***********************************************************************/
class JOUTPRT : public JOUTFILE {
public:
JOUTPRT(PGLOBAL g, FILE *str) : JOUTFILE(g, str) {M = 0; B = false;}
JOUTPRT(PGLOBAL g, FILE *str) : JOUTFILE(g, str, 2) {M = 0; B = false;}
virtual bool WriteStr(const char *s);
virtual bool WriteChr(const char c);
@@ -118,7 +121,8 @@ class JOUTPRT : public JOUTFILE {
/***********************************************************************/
class JPAIR : public BLOCK {
friend class JOBJECT;
friend PJOB ParseObject(PGLOBAL, int&, STRG&);
friend class JSNX;
friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB);
public:
JPAIR(PSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;}
@@ -145,28 +149,32 @@ class JSON : public BLOCK {
virtual JTYP GetType(void) {return TYPE_JSON;}
virtual JTYP GetValType(void) {X return TYPE_JSON;}
virtual void InitArray(PGLOBAL g) {X}
virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL) {X return NULL;}
//virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL) {X return NULL;}
virtual PJPR AddPair(PGLOBAL g, PSZ key) {X return NULL;}
virtual PJVAL GetValue(const char *key) {X return NULL;}
virtual PJAR GetKeyList(PGLOBAL g) {X return NULL;}
virtual PJVAL GetValue(const char *key) {X return NULL;}
virtual PJOB GetObject(void) {return NULL;}
virtual PJAR GetArray(void) {return NULL;}
virtual PJVAL GetValue(int i) {X return NULL;}
virtual PJVAL GetValue(int i) {X return NULL;}
virtual PVAL GetValue(void) {X return NULL;}
virtual PJSON GetJson(void) {X return NULL;}
virtual PJSON GetJsp(void) { X return NULL; }
virtual PJSON GetJson(void) { X return NULL; }
virtual PJPR GetFirst(void) {X return NULL;}
virtual int GetInteger(void) {X return 0;}
virtual double GetFloat() {X return 0.0;}
virtual PSZ GetString() {X return NULL;}
virtual PSZ GetText(PGLOBAL g, PSZ text) {X return NULL;}
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i) {X return true;}
virtual bool Merge(PGLOBAL g, PJSON jsp) { X return true; }
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i) { X return true; }
virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key) {X}
virtual void SetValue(PVAL valp) {X}
virtual void SetValue(PJSON jsp) {X}
virtual void SetString(PGLOBAL g, PSZ s) {X}
virtual void SetString(PGLOBAL g, PSZ s, short c) {X}
virtual void SetInteger(PGLOBAL g, int n) {X}
virtual void SetFloat(PGLOBAL g, double f) {X}
virtual bool DeleteValue(int i) {X return true;}
virtual bool IsNull(void) {X return true;}
virtual void DeleteKey(char *k) {X}
virtual bool DeleteValue(int i) {X return true;}
virtual bool IsNull(void) {X return true;}
protected:
int Size;
@@ -176,8 +184,9 @@ class JSON : public BLOCK {
/* Class JOBJECT: contains a list of value pairs. */
/***********************************************************************/
class JOBJECT : public JSON {
friend PJOB ParseObject(PGLOBAL, int&, STRG&);
friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB);
friend class JSNX;
public:
JOBJECT(void) : JSON() {First = Last = NULL;}
@@ -189,9 +198,12 @@ class JOBJECT : public JSON {
virtual PJPR AddPair(PGLOBAL g, PSZ key);
virtual PJOB GetObject(void) {return this;}
virtual PJVAL GetValue(const char* key);
virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key);
virtual bool IsNull(void);
virtual PJAR GetKeyList(PGLOBAL g);
virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key);
virtual void DeleteKey(char *k);
virtual bool IsNull(void);
protected:
PJPR First;
@@ -202,7 +214,7 @@ class JOBJECT : public JSON {
/* Class JARRAY. */
/***********************************************************************/
class JARRAY : public JSON {
friend PJAR ParseArray(PGLOBAL, int&, STRG&);
friend PJAR ParseArray(PGLOBAL, int&, STRG&, bool*);
public:
JARRAY(void) : JSON() {Alloc = 0; First = Last = NULL; Mvals = NULL;}
@@ -211,10 +223,11 @@ class JARRAY : public JSON {
virtual void Clear(void) {First = Last = NULL; Size = 0;}
virtual JTYP GetType(void) {return TYPE_JAR;}
virtual PJAR GetArray(void) {return this;}
virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL);
PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
virtual void InitArray(PGLOBAL g);
virtual PJVAL GetValue(int i);
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i);
virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i);
virtual bool DeleteValue(int n);
virtual bool IsNull(void);
@@ -231,7 +244,8 @@ class JARRAY : public JSON {
/***********************************************************************/
class JVALUE : public JSON {
friend class JARRAY;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&);
friend class JSNX;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeValue(JOUT *, PJVAL);
public:
JVALUE(void) : JSON()
@@ -239,6 +253,7 @@ class JVALUE : public JSON {
JVALUE(PJSON jsp) : JSON()
{Jsp = jsp; Value = NULL; Next = NULL; Del = false;}
JVALUE(PGLOBAL g, PVAL valp);
JVALUE(PGLOBAL g, PSZ strp);
using JSON::GetValue;
using JSON::SetValue;
@@ -249,17 +264,21 @@ class JVALUE : public JSON {
virtual PJOB GetObject(void);
virtual PJAR GetArray(void);
virtual PVAL GetValue(void) {return Value;}
virtual PJSON GetJson(void) {return (Jsp ? Jsp : this);}
virtual int GetInteger(void);
virtual double GetFloat(void);
virtual PJSON GetJsp(void) {return Jsp;}
virtual PJSON GetJson(void) { return (Jsp ? Jsp : this); }
virtual int GetInteger(void);
virtual long long GetBigint(void);
virtual double GetFloat(void);
virtual PSZ GetString(void);
virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual void SetValue(PVAL valp) {Value = valp;}
virtual void SetValue(PJSON jsp) {Jsp = jsp;}
virtual void SetString(PGLOBAL g, PSZ s);
virtual void SetValue(PJSON jsp);
virtual void SetValue(PVAL valp) { Value = valp; Jsp = NULL; }
virtual void SetString(PGLOBAL g, PSZ s, short c = 0);
virtual void SetInteger(PGLOBAL g, int n);
virtual void SetFloat(PGLOBAL g, double f);
virtual bool IsNull(void);
virtual void SetBigint(PGLOBAL g, longlong ll);
virtual void SetFloat(PGLOBAL g, double f);
virtual void SetTiny(PGLOBAL g, char f);
virtual bool IsNull(void);
protected:
PJSON Jsp; // To the json value

File diff suppressed because it is too large Load Diff

292
storage/connect/jsonudf.h Normal file
View File

@@ -0,0 +1,292 @@
/******************** tabjson H Declares Source Code File (.H) *******************/
/* Name: jsonudf.h Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2015 */
/* */
/* This file contains the JSON UDF function and class declares. */
/*********************************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "block.h"
#include "osutil.h"
#include "maputil.h"
#include "json.h"
#define UDF_EXEC_ARGS \
UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char*, char*
/*********************************************************************************/
/* The JSON tree node. Can be an Object or an Array. */
/*********************************************************************************/
typedef struct _jnode {
PSZ Key; // The key used for object
OPVAL Op; // Operator used for this node
PVAL CncVal; // To cont value used for OP_CNC
PVAL Valp; // The internal array VALUE
int Rank; // The rank in array
int Rx; // Read row number
int Nx; // Next to read row number
} JNODE, *PJNODE;
typedef class JSNX *PJSNX;
typedef class JOUTPATH *PJTP;
typedef class JOUTALL *PJTA;
extern "C" {
DllExport my_bool jsonvalue_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jsonvalue(UDF_EXEC_ARGS);
DllExport void jsonvalue_deinit(UDF_INIT*);
DllExport my_bool json_array_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array(UDF_EXEC_ARGS);
DllExport void json_array_deinit(UDF_INIT*);
DllExport my_bool json_array_add_values_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array_add_values(UDF_EXEC_ARGS);
DllExport void json_array_add_values_deinit(UDF_INIT*);
DllExport my_bool json_array_add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array_add(UDF_EXEC_ARGS);
DllExport void json_array_add_deinit(UDF_INIT*);
DllExport my_bool json_array_delete_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array_delete(UDF_EXEC_ARGS);
DllExport void json_array_delete_deinit(UDF_INIT*);
DllExport my_bool json_object_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object(UDF_EXEC_ARGS);
DllExport void json_object_deinit(UDF_INIT*);
DllExport my_bool json_object_nonull_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_nonull(UDF_EXEC_ARGS);
DllExport void json_object_nonull_deinit(UDF_INIT*);
DllExport my_bool json_object_key_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_key(UDF_EXEC_ARGS);
DllExport void json_object_key_deinit(UDF_INIT*);
DllExport my_bool json_object_add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_add(UDF_EXEC_ARGS);
DllExport void json_object_add_deinit(UDF_INIT*);
DllExport my_bool json_object_delete_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_delete(UDF_EXEC_ARGS);
DllExport void json_object_delete_deinit(UDF_INIT*);
DllExport my_bool json_object_list_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_list(UDF_EXEC_ARGS);
DllExport void json_object_list_deinit(UDF_INIT*);
DllExport my_bool json_array_grp_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport void json_array_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *);
DllExport char *json_array_grp(UDF_EXEC_ARGS);
DllExport void json_array_grp_clear(UDF_INIT *, char *, char *);
DllExport void json_array_grp_deinit(UDF_INIT*);
DllExport my_bool json_object_grp_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport void json_object_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *);
DllExport char *json_object_grp(UDF_EXEC_ARGS);
DllExport void json_object_grp_clear(UDF_INIT *, char *, char *);
DllExport void json_object_grp_deinit(UDF_INIT*);
DllExport my_bool json_item_merge_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_item_merge(UDF_EXEC_ARGS);
DllExport void json_item_merge_deinit(UDF_INIT*);
DllExport my_bool json_get_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_get_item(UDF_EXEC_ARGS);
DllExport void json_get_item_deinit(UDF_INIT*);
DllExport my_bool jsonget_string_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jsonget_string(UDF_EXEC_ARGS);
DllExport void jsonget_string_deinit(UDF_INIT*);
DllExport my_bool jsonget_int_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport long long jsonget_int(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonget_int_deinit(UDF_INIT*);
DllExport my_bool jsonget_real_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport double jsonget_real(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonget_real_deinit(UDF_INIT*);
DllExport my_bool jsoncontains_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport long long jsoncontains(UDF_EXEC_ARGS);
DllExport void jsoncontains_deinit(UDF_INIT*);
DllExport my_bool jsonlocate_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jsonlocate(UDF_EXEC_ARGS);
DllExport void jsonlocate_deinit(UDF_INIT*);
DllExport my_bool json_locate_all_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_locate_all(UDF_EXEC_ARGS);
DllExport void json_locate_all_deinit(UDF_INIT*);
DllExport my_bool jsoncontains_path_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport long long jsoncontains_path(UDF_EXEC_ARGS);
DllExport void jsoncontains_path_deinit(UDF_INIT*);
DllExport my_bool json_set_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_set_item(UDF_EXEC_ARGS);
DllExport void json_set_item_deinit(UDF_INIT*);
DllExport my_bool json_insert_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_insert_item(UDF_EXEC_ARGS);
DllExport void json_insert_item_deinit(UDF_INIT*);
DllExport my_bool json_update_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_update_item(UDF_EXEC_ARGS);
DllExport void json_update_item_deinit(UDF_INIT*);
DllExport my_bool json_file_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_file(UDF_EXEC_ARGS);
DllExport void json_file_deinit(UDF_INIT*);
DllExport my_bool jfile_make_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jfile_make(UDF_EXEC_ARGS);
DllExport void jfile_make_deinit(UDF_INIT*);
DllExport my_bool jbin_array_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_array(UDF_EXEC_ARGS);
DllExport void jbin_array_deinit(UDF_INIT*);
DllExport my_bool jbin_array_add_values_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_array_add_values(UDF_EXEC_ARGS);
DllExport void jbin_array_add_values_deinit(UDF_INIT*);
DllExport my_bool jbin_array_add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_array_add(UDF_EXEC_ARGS);
DllExport void jbin_array_add_deinit(UDF_INIT*);
DllExport my_bool jbin_array_delete_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_array_delete(UDF_EXEC_ARGS);
DllExport void jbin_array_delete_deinit(UDF_INIT*);
DllExport my_bool jbin_object_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object(UDF_EXEC_ARGS);
DllExport void jbin_object_deinit(UDF_INIT*);
DllExport my_bool jbin_object_nonull_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_nonull(UDF_EXEC_ARGS);
DllExport void jbin_object_nonull_deinit(UDF_INIT*);
DllExport my_bool jbin_object_key_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_key(UDF_EXEC_ARGS);
DllExport void jbin_object_key_deinit(UDF_INIT*);
DllExport my_bool jbin_object_add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_add(UDF_EXEC_ARGS);
DllExport void jbin_object_add_deinit(UDF_INIT*);
DllExport my_bool jbin_object_delete_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_delete(UDF_EXEC_ARGS);
DllExport void jbin_object_delete_deinit(UDF_INIT*);
DllExport my_bool jbin_object_list_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_list(UDF_EXEC_ARGS);
DllExport void jbin_object_list_deinit(UDF_INIT*);
DllExport my_bool jbin_get_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_get_item(UDF_EXEC_ARGS);
DllExport void jbin_get_item_deinit(UDF_INIT*);
DllExport my_bool jbin_item_merge_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_item_merge(UDF_EXEC_ARGS);
DllExport void jbin_item_merge_deinit(UDF_INIT*);
DllExport my_bool jbin_set_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_set_item(UDF_EXEC_ARGS);
DllExport void jbin_set_item_deinit(UDF_INIT*);
DllExport my_bool jbin_insert_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_insert_item(UDF_EXEC_ARGS);
DllExport void jbin_insert_item_deinit(UDF_INIT*);
DllExport my_bool jbin_update_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_update_item(UDF_EXEC_ARGS);
DllExport void jbin_update_item_deinit(UDF_INIT*);
DllExport my_bool jbin_file_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_file(UDF_EXEC_ARGS);
DllExport void jbin_file_deinit(UDF_INIT*);
DllExport my_bool json_serialize_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_serialize(UDF_EXEC_ARGS);
DllExport void json_serialize_deinit(UDF_INIT*);
} // extern "C"
/*********************************************************************************/
/* Structure JPN. Used to make the locate path. */
/*********************************************************************************/
typedef struct _jpn {
enum JTYP Type;
PSZ Key;
int N;
} JPN, *PJPN;
/*********************************************************************************/
/* Class JSNX: JSON access method. */
/*********************************************************************************/
class JSNX : public BLOCK {
public:
// Constructors
JSNX(PGLOBAL g, PJSON row, int type, int len = 64, int prec = 0, my_bool wr = false);
// Implementation
int GetPrecision(void) {return Prec;}
PVAL GetValue(void) {return Value;}
// Methods
my_bool SetJpath(PGLOBAL g, char *path, my_bool jb = false);
my_bool ParseJpath(PGLOBAL g);
void ReadValue(PGLOBAL g);
PJVAL GetRowValue(PGLOBAL g, PJSON row, int i, my_bool b = true);
PJVAL GetJson(PGLOBAL g);
my_bool CheckPath(PGLOBAL g);
my_bool WriteValue(PGLOBAL g, PJVAL jvalp);
char *Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k = 1);
char *LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx = 10);
protected:
my_bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm);
PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
PVAL ExpandArray(PGLOBAL g, PJAR arp, int n);
PVAL CalculateArray(PGLOBAL g, PJAR arp, int n);
PVAL MakeJson(PGLOBAL g, PJSON jsp);
void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n);
PJSON GetRow(PGLOBAL g);
my_bool LocateArray(PJAR jarp);
my_bool LocateObject(PJOB jobp);
my_bool LocateValue(PJVAL jvp);
my_bool LocateArrayAll(PJAR jarp);
my_bool LocateObjectAll(PJOB jobp);
my_bool LocateValueAll(PJVAL jvp);
my_bool CompareTree(PJSON jp1, PJSON jp2);
my_bool AddPath(void);
// Default constructor not to be used
JSNX(void) {}
// Members
PJSON Row;
PJVAL Jvalp;
PJPN Jpnp;
JOUTSTR *Jp;
JNODE *Nodes; // The intermediate objects
PVAL Value;
PVAL MulVal; // To value used by multiple column
char *Jpath; // The json path
int Buf_Type;
int Long;
int Prec;
int Nod; // The number of intermediate objects
int Xnod; // Index of multiple values
int K; // Kth item to locate
int I; // Index of JPN
int Imax; // Max number of JPN's
int B; // Index base
my_bool Xpd; // True for expandable column
my_bool Parsed; // True when parsed
my_bool Found; // Item found by locate
my_bool Wr; // Write mode
my_bool Jb; // Must return json item
}; // end of class JSNX

View File

@@ -89,6 +89,7 @@
#if defined(XML_SUPPORT)
#include "tabxml.h"
#endif // XML_SUPPORT
#include "mycat.h"
/***********************************************************************/
/* Extern static variables. */
@@ -299,13 +300,13 @@ int GetIndexType(TABTYPE type)
xtyp= 1;
break;
case TAB_MYSQL:
// case TAB_ODBC:
case TAB_ODBC:
xtyp= 2;
break;
case TAB_VIR:
xtyp= 3;
break;
case TAB_ODBC:
// case TAB_ODBC:
default:
xtyp= 0;
break;

View File

@@ -74,6 +74,7 @@ struct ha_table_option_struct {
typedef class ha_connect *PHC;
char *GetPluginDir(void);
TABTYPE GetTypeID(const char *type);
bool IsFileType(TABTYPE type);
bool IsExactType(TABTYPE type);

View File

@@ -30,3 +30,30 @@ SELECT id, TIME(tim) FROM t1 LIMIT 1;
id TIME(tim)
1 09:35:08.000000
DROP TABLE t1;
#
# Testing use of dates in where clause (MDEV-8926)
#
CREATE TABLE t1 (col1 DATE) ENGINE=CONNECT TABLE_TYPE=CSV;
Warnings:
Warning 1105 No file name. Table will use t1.csv
INSERT INTO t1 VALUES('2015-01-01'),('2015-02-01'),('2015-03-01'),('2015-04-01');
SELECT * FROM t1 WHERE col1 = '2015-02-01';
col1
2015-02-01
SELECT * FROM t1 WHERE col1 > '2015-02-01';
col1
2015-03-01
2015-04-01
SELECT * FROM t1 WHERE col1 >= '2015-02-01';
col1
2015-02-01
2015-03-01
2015-04-01
SELECT * FROM t1 WHERE col1 < '2015-02-01';
col1
2015-01-01
SELECT * FROM t1 WHERE col1 <= '2015-02-01';
col1
2015-01-01
2015-02-01
DROP TABLE t1;

View File

@@ -1,3 +1,4 @@
set sql_mode="";
#
# Testing FILE privilege
#
@@ -46,7 +47,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
@@ -70,6 +71,7 @@ DROP USER user@localhost;
#
# Beginning of grant.inc
#
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
SELECT user();
@@ -130,7 +132,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
@@ -164,6 +166,7 @@ DROP USER user@localhost;
#
# Beginning of grant.inc
#
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
SELECT user();
@@ -224,7 +227,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
@@ -258,6 +261,7 @@ DROP USER user@localhost;
#
# Beginning of grant.inc
#
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
SELECT user();
@@ -318,7 +322,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
@@ -352,6 +356,7 @@ DROP USER user@localhost;
#
# Beginning of grant.inc
#
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
SELECT user();
@@ -412,7 +417,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
@@ -446,6 +451,7 @@ DROP USER user@localhost;
#
# Beginning of grant.inc
#
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
SELECT user();
@@ -506,7 +512,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
@@ -537,3 +543,4 @@ DROP USER user@localhost;
#
# End of grant.inc
#
set sql_mode=default;

View File

@@ -1,8 +1,10 @@
#
# Checking FILE privileges
#
set sql_mode="";
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
set sql_mode=default;
SELECT user();
user()
user@localhost
@@ -59,7 +61,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost

View File

@@ -171,6 +171,40 @@ line
]
DROP TABLE t1;
#
# Testing a pretty=0 file
#
CREATE TABLE t1
(
ISBN CHAR(15) NOT NULL,
Language CHAR(2) FIELD_FORMAT='LANG',
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
Title CHAR(32) FIELD_FORMAT='TITLE',
Translation CHAR(32) FIELD_FORMAT='TRANSLATED:PREFIX',
TranslatorFN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:FIRSTNAME',
TranslatorLN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:LASTNAME',
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
Year int(4) FIELD_FORMAT='DATEPUB',
INDEX IX(ISBN)
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bib0.json' LRECL=320 OPTION_LIST='Pretty=0';
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 IX 1 ISBN A NULL NULL NULL XINDEX
SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation TranslatorFN TranslatorLN Publisher Location Year
9782212090819 fr applications Jean-Michel Bernadac Construire une application XML NULL NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Fran<61>ois Knab Construire une application XML NULL NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt<70> de l'anglais par James Guerin Microsoft Press Paris 2001
DESCRIBE SELECT * FROM t1 WHERE ISBN = '9782212090819';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref IX IX 15 const 1 Using where
UPDATE t1 SET AuthorFN = 'Philippe' WHERE ISBN = '9782212090819';
ERROR HY000: Got error 122 'Cannot write expanded column when Pretty is not 2' from CONNECT
DROP TABLE t1;
#
# A file with 2 arrays
#
CREATE TABLE t1 (

View File

@@ -1,63 +1,177 @@
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=VIR BLOCK_SIZE=5;
#
# Test UDF's with constant arguments
#
SELECT JsonValue(56, 3.1416, 'foo', NULL);
ERROR HY000: Can't initialize function 'jsonvalue'; Cannot accept more than 1 argument
SELECT JsonValue(3.1416);
JsonValue(3.1416)
3.141600
SELECT JsonValue(-80);
JsonValue(-80)
-80
SELECT JsonValue('foo');
JsonValue('foo')
"foo"
SELECT JsonValue(9223372036854775807);
JsonValue(9223372036854775807)
9223372036854775807
SELECT JsonValue(NULL);
JsonValue(NULL)
null
SELECT JsonValue(TRUE);
JsonValue(TRUE)
true
SELECT JsonValue(FALSE);
JsonValue(FALSE)
false
SELECT JsonValue();
JsonValue()
null
SELECT JsonValue('[11, 22, 33]' json_) FROM t1;
JsonValue('[11, 22, 33]' json_)
[11,22,33]
[11,22,33]
[11,22,33]
[11,22,33]
[11,22,33]
SELECT Json_Array();
Json_Array()
[]
SELECT Json_Object(56,3.1416,'foo',NULL);
Json_Object(56,3.1416,'foo',NULL)
{"56":56,"3.1416":3.141600,"foo":"foo","NULL":null}
SELECT Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty);
Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty)
{"qty":56,"price":3.141600,"truc":"foo","garanty":null}
SELECT Json_Array(56,3.1416,'My name is "Foo"',NULL);
Json_Array(56,3.1416,'My name is "Foo"',NULL)
SELECT Json_Array(56, 3.1416, 'My name is "Foo"', NULL);
Json_Array(56, 3.1416, 'My name is "Foo"', NULL)
[56,3.141600,"My name is \"Foo\"",null]
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL)) Array;
ERROR HY000: Can't initialize function 'Json_Array_Add'; Json_Value_Add must have at least 2 arguments
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL),'One more') Array;
SELECT Json_Array(Json_Array(56, 3.1416, 'foo'), TRUE);
Json_Array(Json_Array(56, 3.1416, 'foo'), TRUE)
[[56,3.141600,"foo"],true]
SELECT Json_Array_Add(Json_Array(56, 3.1416, 'foo', NULL)) Array;
ERROR HY000: Can't initialize function 'json_array_add'; This function must have at least 2 arguments
SELECT Json_Array_Add(Json_Array(56, 3.1416, 'foo', NULL), 'One more') Array;
Array
[56,3.141600,"foo",null,"One more"]
SELECT Json_Array_Add(Json_Value('one value'),'One more');
Json_Array_Add(Json_Value('one value'),'One more')
["one value","One more"]
SELECT Json_Array_Add('one value','One more');
ERROR HY000: Can't initialize function 'Json_Array_Add'; Json_Value_Add first argument must be a json item
SELECT Json_Array_Add('one value' json_,'One more');
Json_Array_Add('one value' json_,'One more')
[null,"One more"]
SELECT Json_Array_Add(JsonValue('one value'), 'One more');
ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
SELECT Json_Array_Add('one value', 'One more');
ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
SELECT Json_Array_Add('one value' json_, 'One more');
Json_Array_Add('one value' json_, 'One more')
one value
Warnings:
Warning 1105 Bad 'o' character near one value
SELECT Json_Value(56,3.1416,'foo',NULL);
ERROR HY000: Can't initialize function 'Json_Value'; Json_Value cannot accept more than 1 argument
SELECT Json_Value(3.1416);
Json_Value(3.1416)
3.141600
SELECT Json_Value('foo');
Json_Value('foo')
"foo"
SELECT Json_Value(NULL);
Json_Value(NULL)
null
SELECT Json_Value();
Json_Value()
null
Warning 1105 Error 2 opening one value
Warning 1105 First argument target is not an array
SELECT Json_Array_Add(5 json_, 'One more');
ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 0)
[4,5,3,8,7,9]
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
Array
[5,3,4,8,7,9]
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 9);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 9)
[5,3,8,7,9,4]
SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), '[2]', 33, 1);
Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), '[2]', 33, 1)
[1,2,[11,22],"[2]"]
SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, '[2]', 1);
Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, '[2]', 1)
[1,2,[11,33,22]]
SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, 1, '[2]');
Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, 1, '[2]')
[1,2,[11,33,22]]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
Array
[56,3.141600,"machin",null,"One more","Two more"]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
Array
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), n) Array FROM t1;
Array
[56,3.141600,"machin",1]
[56,3.141600,"machin",2]
[56,3.141600,"machin",3]
[56,3.141600,"machin",4]
[56,3.141600,"machin",5]
SELECT Json_Array_Add_Values(Json_Array(n, 3.1416, 'machin'), n) Array FROM t1;
Array
[1,3.141600,"machin",1]
[2,3.141600,"machin",2]
[3,3.141600,"machin",3]
[4,3.141600,"machin",4]
[5,3.141600,"machin",5]
SELECT Json_Array_Add_Values('[56]', 3.1416, 'machin') Array;
Array
[56,3.141600,"machin"]
SELECT Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), 0);
Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), 0)
[3.141600,"My name is \"Foo\"",null]
SELECT Json_Array_Delete(Json_Object(56, 3.1416, 'My name is Foo', NULL), 2);
Json_Array_Delete(Json_Object(56, 3.1416, 'My name is Foo', NULL), 2)
{"56":56,"3.1416":3.141600,"My name is Foo":"My name is Foo","NULL":null}
Warnings:
Warning 1105 First argument target is not an array
SELECT Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), '2');
Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), '2')
[56,3.141600,"My name is \"Foo\"",null]
Warnings:
Warning 1105 Missing or null array index
SELECT Json_Array_Delete(json_array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2);
Json_Array_Delete(json_array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2)
[56,3.141600,"My name is \"Foo\"",null]
Warnings:
Warning 1105 No sub-item at '2'
SELECT Json_Object(56, 3.1416, 'foo', NULL);
Json_Object(56, 3.1416, 'foo', NULL)
{"56":56,"3.1416":3.141600,"foo":"foo","NULL":null}
SELECT Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty)
{"qty":56,"price":3.141600,"truc":"foo","garanty":null}
SELECT Json_Object();
Json_Object()
{}
SELECT Json_Object(Json_Array(56,3.1416,'foo'),NULL);
Json_Object(Json_Array(56,3.1416,'foo'),NULL)
{"Array(56,3.1416,'foo')":[56,3.141600,"foo"],"NULL":null}
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL);
Json_Array(Json_Array(56,3.1416,'foo'),NULL)
[[56,3.141600,"foo"],null]
SELECT Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL);
Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL)
SELECT Json_Object(Json_Array(56, 3.1416, 'foo'), NULL);
Json_Object(Json_Array(56, 3.1416, 'foo'), NULL)
{"Array(56, 3.1416, 'foo')":[56,3.141600,"foo"],"NULL":null}
SELECT Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL)
[{"qty":56,"price":3.141600,"foo":"foo"},null]
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL);
Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL)
{"qty":56,"price":3.141600,"truc":"machin","garanty":null}
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty');
ERROR HY000: Can't initialize function 'json_object_key'; This function must have an even number of arguments
SELECT Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color)
{"qty":56,"price":3.141600,"truc":"machin","garanty":null,"color":"blue"}
SELECT Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price)
{"qty":56,"price":45.990000,"truc":"machin","garanty":null}
SELECT Json_Object_Add(Json_File('notexist.json'), 'cheese' item, '[1]', 1);
Json_Object_Add(Json_File('notexist.json'), 'cheese' item, '[1]', 1)
NULL
Warnings:
Warning 1105 Error 2 opening notexist.json
Warning 1105 First argument target is not an object
SELECT Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc');
Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc')
{"qty":56,"price":3.141600,"garanty":null}
SELECT Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose');
Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose')
{"qty":56,"price":3.141600,"truc":"machin","garanty":null}
SELECT Json_Object_List(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty)) "Key List";
Key List
["qty","price","truc","garanty"]
SELECT Json_Object_List('{"qty":56, "price":3.1416, "truc":"machin", "garanty":null}') "Key List";
Key List
["qty","price","truc","garanty"]
#
# Test UDF's with column arguments
#
CREATE TABLE t1
CREATE TABLE t2
(
ISBN CHAR(15),
LANG CHAR(2),
@@ -69,21 +183,20 @@ TRANSLATOR CHAR(80),
PUBLISHER CHAR(32),
DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t1;
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
Json_Array(AUTHOR, TITLE, DATEPUB)
["Jean-Christophe Bernadac","Construire une application XML",1999]
["William J. Pardi","XML en Action",1999]
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t1;
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
Json_Object(AUTHOR, TITLE, DATEPUB)
{"AUTHOR":"Jean-Christophe Bernadac","TITLE":"Construire une application XML","DATEPUB":1999}
{"AUTHOR":"William J. Pardi","TITLE":"XML en Action","DATEPUB":1999}
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t1;
ERROR HY000: Can't initialize function 'Json_Array_Grp'; Json_Array_Grp can only accept 1 argument
SELECT Json_Array_Grp(TITLE) FROM t1;
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t2;
ERROR HY000: Can't initialize function 'json_array_grp'; This function can only accept 1 argument
SELECT Json_Array_Grp(TITLE) FROM t2;
Json_Array_Grp(TITLE)
["Construire une application XML","XML en Action"]
DROP TABLE t1;
CREATE TABLE t1 (
CREATE TABLE t3 (
SERIALNO CHAR(5) NOT NULL,
NAME VARCHAR(12) NOT NULL FLAG=6,
SEX SMALLINT(1) NOT NULL,
@@ -93,10 +206,10 @@ DEPARTMENT CHAr(4) NOT NULL FLAG=41,
SECRETARY CHAR(5) DEFAULT NULL FLAG=46,
SALARY DOUBLE(8,2) NOT NULL FLAG=52
) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1;
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t1 WHERE NAME = 'MERCHANT';
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
Json_Object(SERIALNO, NAME, TITLE, SALARY)
{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000}
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t1 GROUP BY DEPARTMENT;
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT;
DEPARTMENT Json_Array_Grp(NAME)
0021 ["STRONG","SHORTSIGHT"]
0318 ["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]
@@ -104,26 +217,36 @@ DEPARTMENT Json_Array_Grp(NAME)
2452 ["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]
Warnings:
Warning 1105 Result truncated to json_grp_size values
set connect_json_grp_size=30;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t1 GROUP BY DEPARTMENT;
SET connect_json_grp_size=30;
SELECT Json_Object(title, Json_Array_Grp(name) `json_names`) from t3 GROUP BY title;
Json_Object(title, Json_Array_Grp(name) `json_names`)
{"title":"ADMINISTRATOR","names":["GOOSEPEN","FUNNIGUY","SHRINKY"]}
{"title":"DIRECTOR","names":["QUINN","WERTHER","STRONG"]}
{"title":"ENGINEER","names":["BROWNY","ORELLY","MARTIN","TONGHO","WALTER","SMITH"]}
{"title":"PROGRAMMER","names":["BUGHAPPY"]}
{"title":"SALESMAN","names":["WHEELFOR","MERCHANT","BULLOZER","BANCROFT","FODDERMAN"]}
{"title":"SCIENTIST","names":["BIGHEAD","BIGHORN"]}
{"title":"SECRETARY","names":["MESSIFUL","HONEY","SHORTSIGHT","CHERRY","MONAPENNY"]}
{"title":"TYPIST","names":["KITTY","PLUMHEAD"]}
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
Json_Array(DEPARTMENT, Json_Array_Grp(NAME))
["0021",["STRONG","SHORTSIGHT"]]
["0318",["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]]
["0319",["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]]
["2452",["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]]
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES)
{"DEPARTMENT":"0021","NAMES":["STRONG","SHORTSIGHT"]}
{"DEPARTMENT":"0318","NAMES":["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]}
{"DEPARTMENT":"0319","NAMES":["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]}
{"DEPARTMENT":"2452","NAMES":["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]}
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES)
{"DEPARTMENT":"0021","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","TITLE":"DIRECTOR","SALARY":23000.000000},{"SERIALNO":"22222","NAME":"SHORTSIGHT","TITLE":"SECRETARY","SALARY":5500.000000}]}
{"DEPARTMENT":"0318","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","TITLE":"SALESMAN","SALARY":9600.000000},{"SERIALNO":"24888","NAME":"PLUMHEAD","TITLE":"TYPIST","SALARY":2800.000000},{"SERIALNO":"27845","NAME":"HONEY","TITLE":"SECRETARY","SALARY":4900.000000},{"SERIALNO":"73452","NAME":"TONGHO","TITLE":"ENGINEER","SALARY":6800.000000},{"SERIALNO":"74234","NAME":"WALTER","TITLE":"ENGINEER","SALARY":7400.000000},{"SERIALNO":"77777","NAME":"SHRINKY","TITLE":"ADMINISTRATOR","SALARY":7500.000000},{"SERIALNO":"70012","NAME":"WERTHER","TITLE":"DIRECTOR","SALARY":14500.000000},{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000},{"SERIALNO":"73111","NAME":"WHEELFOR","TITLE":"SALESMAN","SALARY":10030.000000}]}
{"DEPARTMENT":"0319","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","TITLE":"SALESMAN","SALARY":14800.000000},{"SERIALNO":"40567","NAME":"QUINN","TITLE":"DIRECTOR","SALARY":14000.000000},{"SERIALNO":"00137","NAME":"BROWNY","TITLE":"ENGINEER","SALARY":10500.000000},{"SERIALNO":"12345","NAME":"KITTY","TITLE":"TYPIST","SALARY":3000.450000},{"SERIALNO":"33333","NAME":"MONAPENNY","TITLE":"SECRETARY","SALARY":3800.000000},{"SERIALNO":"00023","NAME":"MARTIN","TITLE":"ENGINEER","SALARY":10000.000000},{"SERIALNO":"07654","NAME":"FUNNIGUY","TITLE":"ADMINISTRATOR","SALARY":8500.000000},{"SERIALNO":"45678","NAME":"BUGHAPPY","TITLE":"PROGRAMMER","SALARY":8500.000000},{"SERIALNO":"56789","NAME":"FODDERMAN","TITLE":"SALESMAN","SALARY":7000.000000},{"SERIALNO":"55555","NAME":"MESSIFUL","TITLE":"SECRETARY","SALARY":5000.500000},{"SERIALNO":"98765","NAME":"GOOSEPEN","TITLE":"ADMINISTRATOR","SALARY":4700.000000}]}
{"DEPARTMENT":"2452","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","TITLE":"SCIENTIST","SALARY":8000.000000},{"SERIALNO":"31416","NAME":"ORELLY","TITLE":"ENGINEER","SALARY":13400.000000},{"SERIALNO":"36666","NAME":"BIGHORN","TITLE":"SCIENTIST","SALARY":11000.000000},{"SERIALNO":"02345","NAME":"SMITH","TITLE":"ENGINEER","SALARY":9000.000000},{"SERIALNO":"11111","NAME":"CHERRY","TITLE":"SECRETARY","SALARY":4500.000000}]}
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT, TITLE;
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES)
{"DEPARTMENT":"0021","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","SALARY":23000.000000}]}
{"DEPARTMENT":"0021","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"22222","NAME":"SHORTSIGHT","SALARY":5500.000000}]}
@@ -143,25 +266,382 @@ Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY
{"DEPARTMENT":"2452","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"31416","NAME":"ORELLY","SALARY":13400.000000},{"SERIALNO":"02345","NAME":"SMITH","SALARY":9000.000000}]}
{"DEPARTMENT":"2452","TITLE":"SCIENTIST","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","SALARY":8000.000000},{"SERIALNO":"36666","NAME":"BIGHORN","SALARY":11000.000000}]}
{"DEPARTMENT":"2452","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"11111","NAME":"CHERRY","SALARY":4500.000000}]}
SELECT Json_Object_Grp(SALARY) FROM t1;
ERROR HY000: Can't initialize function 'Json_Object_Grp'; Json_Array_Grp can only accept 2 arguments
SELECT Json_Object_Grp(SALARY, NAME) FROM t1;
Json_Object_Grp(SALARY, NAME)
SELECT Json_Object_Grp(SALARY) FROM t3;
ERROR HY000: Can't initialize function 'json_object_grp'; This function requires 2 arguments (key, value)
SELECT Json_Object_Grp(NAME, SALARY) FROM t3;
Json_Object_Grp(NAME, SALARY)
{"BANCROFT":9600.000000,"SMITH":9000.000000,"MERCHANT":8700.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"BIGHEAD":8000.000000,"SHRINKY":7500.000000,"WALTER":7400.000000,"FODDERMAN":7000.000000,"TONGHO":6800.000000,"SHORTSIGHT":5500.000000,"MESSIFUL":5000.500000,"HONEY":4900.000000,"GOOSEPEN":4700.000000,"CHERRY":4500.000000,"MONAPENNY":3800.000000,"KITTY":3000.450000,"PLUMHEAD":2800.000000,"STRONG":23000.000000,"BULLOZER":14800.000000,"WERTHER":14500.000000,"QUINN":14000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"BROWNY":10500.000000,"WHEELFOR":10030.000000,"MARTIN":10000.000000}
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t1 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES")
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES")
{"DEPARTMENT":"0021","SALARIES":{"STRONG":23000.000000,"SHORTSIGHT":5500.000000}}
{"DEPARTMENT":"0318","SALARIES":{"BANCROFT":9600.000000,"PLUMHEAD":2800.000000,"HONEY":4900.000000,"TONGHO":6800.000000,"WALTER":7400.000000,"SHRINKY":7500.000000,"WERTHER":14500.000000,"MERCHANT":8700.000000,"WHEELFOR":10030.000000}}
{"DEPARTMENT":"0319","SALARIES":{"BULLOZER":14800.000000,"QUINN":14000.000000,"BROWNY":10500.000000,"KITTY":3000.450000,"MONAPENNY":3800.000000,"MARTIN":10000.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"FODDERMAN":7000.000000,"MESSIFUL":5000.500000,"GOOSEPEN":4700.000000}}
{"DEPARTMENT":"2452","SALARIES":{"BIGHEAD":8000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"SMITH":9000.000000,"CHERRY":4500.000000}}
SELECT Json_Array_Grp(NAME) from t1;
SELECT Json_Array_Grp(NAME) FROM t3;
Json_Array_Grp(NAME)
["BANCROFT","SMITH","MERCHANT","FUNNIGUY","BUGHAPPY","BIGHEAD","SHRINKY","WALTER","FODDERMAN","TONGHO","SHORTSIGHT","MESSIFUL","HONEY","GOOSEPEN","CHERRY","MONAPENNY","KITTY","PLUMHEAD","STRONG","BULLOZER","WERTHER","QUINN","ORELLY","BIGHORN","BROWNY","WHEELFOR","MARTIN"]
SELECT Json_Object_Key(name, title) FROM t3 WHERE DEPARTMENT = 318;
Json_Object_Key(name, title)
{"BANCROFT":"SALESMAN"}
{"MERCHANT":"SALESMAN"}
{"SHRINKY":"ADMINISTRATOR"}
{"WALTER":"ENGINEER"}
{"TONGHO":"ENGINEER"}
{"HONEY":"SECRETARY"}
{"PLUMHEAD":"TYPIST"}
{"WERTHER":"DIRECTOR"}
{"WHEELFOR":"SALESMAN"}
SELECT Json_Object_Grp(name, title) FROM t3 WHERE DEPARTMENT = 318;
Json_Object_Grp(name, title)
{"BANCROFT":"SALESMAN","MERCHANT":"SALESMAN","SHRINKY":"ADMINISTRATOR","WALTER":"ENGINEER","TONGHO":"ENGINEER","HONEY":"SECRETARY","PLUMHEAD":"TYPIST","WERTHER":"DIRECTOR","WHEELFOR":"SALESMAN"}
#
# Test value getting UDF's
#
SELECT JsonGet_String(Json_Array_Grp(name),'[#]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[#]')
27
SELECT JsonGet_String(Json_Array_Grp(name),'[","]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[","]')
BANCROFT,SMITH,MERCHANT,FUNNIGUY,BUGHAPPY,BIGHEAD,SHRINKY,WALTER,FODDERMAN,TONGHO,SHORTSIGHT,MESSIFUL,HONEY,GOOSEPEN,CHERRY,MONAPENNY,KITTY,PLUMHEAD,STRONG,BULLOZER,WERTHER,QUINN,ORELLY,BIGHORN,BROWNY,WHEELFOR,MARTIN
SELECT JsonGet_String(Json_Array_Grp(name),'[>]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[>]')
WHEELFOR
SET @j1 = '[45,28,36,45,89]';
SELECT JsonGet_String(@j1,'[1]');
JsonGet_String(@j1,'[1]')
28
SELECT JsonGet_String(@j1 json_,'[3]');
JsonGet_String(@j1 json_,'[3]')
45
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'[3]');
JsonGet_String(Json_Array(45,28,36,45,89),'[3]')
45
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Array(45,28,36,45,89),'[+]') "sum";
list egal sum
45+28+36+45+89 = 243.00
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]')
36
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*');
JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*')
[36,45,89]
SELECT JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc')
machin
SET @j2 = '{"qty":56,"price":3.141600,"truc":"machin","garanty":null}';
SELECT JsonGet_String(@j2 json_,'truc');
JsonGet_String(@j2 json_,'truc')
machin
SELECT JsonGet_String(@j2,'truc');
JsonGet_String(@j2,'truc')
machin
SELECT JsonGet_String(@j2,'chose');
JsonGet_String(@j2,'chose')
NULL
SELECT JsonGet_String(NULL json_, NULL);
JsonGet_String(NULL json_, NULL)
NULL
Warnings:
Warning 1105
SELECT department, JsonGet_String(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500.00
0318 72230.00
0319 89800.95
2452 45900.00
SELECT JsonGet_Int(@j1, '[4]');
JsonGet_Int(@j1, '[4]')
89
SELECT JsonGet_Int(@j1, '[#]');
JsonGet_Int(@j1, '[#]')
5
SELECT JsonGet_Int(@j1, '[+]');
JsonGet_Int(@j1, '[+]')
243
SELECT JsonGet_Int(@j1 json_, '[3]');
JsonGet_Int(@j1 json_, '[3]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '[3]');
JsonGet_Int(Json_Array(45,28,36,45,89), '[3]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '["+"]');
JsonGet_Int(Json_Array(45,28,36,45,89), '["+"]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '[+]');
JsonGet_Int(Json_Array(45,28,36,45,89), '[+]')
243
SELECT JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]');
JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]')
36
SELECT JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[0]:[1]');
JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[0]:[1]')
28
SELECT JsonGet_Int(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty');
JsonGet_Int(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty')
56
SELECT JsonGet_Int(@j2 json_, 'price');
JsonGet_Int(@j2 json_, 'price')
3
SELECT JsonGet_Int(@j2, 'qty');
JsonGet_Int(@j2, 'qty')
56
SELECT JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose');
JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose')
NULL
SELECT JsonGet_Int(JsonGet_String(Json_Array(Json_Array(45,28),Json_Array(36,45,89)), '[1]:*'), '[+]') sum;
sum
170
SELECT department, JsonGet_Int(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"), 'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500
0318 72230
0319 89800
2452 45900
SELECT JsonGet_Real(@j1, '[2]');
JsonGet_Real(@j1, '[2]')
36.000000000000000
SELECT JsonGet_Real(@j1 json_, '[3]', 2);
JsonGet_Real(@j1 json_, '[3]', 2)
45.00
SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[3]');
JsonGet_Real(Json_Array(45,28,36,45,89), '[3]')
45.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '["+"]');
JsonGet_Real(Json_Array(45,28,36,45,89), '["+"]')
45.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[+]');
JsonGet_Real(Json_Array(45,28,36,45,89), '[+]')
243.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[!]');
JsonGet_Real(Json_Array(45,28,36,45,89), '[!]')
48.600000000000000
SELECT JsonGet_Real(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]');
JsonGet_Real(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]')
36.000000000000000
SELECT JsonGet_Real(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price');
JsonGet_Real(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price')
3.141600000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_, 'qty');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_, 'qty')
56.000000000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'price');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'price')
3.141600000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'price', 4);
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'price', 4)
3.1416
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose')
NULL
SELECT department, JsonGet_Real(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500.000000000000000
0318 72230.000000000000000
0319 89800.950000000000000
2452 45900.000000000000000
#
# Documentation examples
#
SELECT
JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";
Rank Number Concat Sum Avg
89 5 45,28,36,45,89 243 48.60
SELECT
JsonGet_String('{"qty":7,"price":29.50,"garanty":null}', 'price') "String",
JsonGet_Int('{"qty":7,"price":29.50,"garanty":null}', 'price') "Int",
JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}', 'price') "Real";
String Int Real
29.50 29 29.500000000000000
SELECT JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}', 'price', 3) "Real";
Real
29.500
#
# Testing Locate
#
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin')
truc
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56)
qty
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416)
price
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose')
NULL
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;
Path
AUTHORS:[1]:FN
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'jack' ci) Path;
Path
AUTHORS:[1]:FN
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"Jack", "LN":"London"}' json_) Path;
Path
AUTHORS:[1]
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"jack", "LN":"London"}' json_) Path;
Path
NULL
SELECT JsonLocate('[45,28,36,45,89]',36);
JsonLocate('[45,28,36,45,89]',36)
[2]
SELECT JsonLocate('[45,28,36,45,89]' json_,28.0);
JsonLocate('[45,28,36,45,89]' json_,28.0)
NULL
SELECT Json_Locate_All('[45,28,36,45,89]',10);
Json_Locate_All('[45,28,36,45,89]',10)
[]
SELECT Json_Locate_All('[45,28,36,45,89]',45);
Json_Locate_All('[45,28,36,45,89]',45)
["[0]","[3]"]
SELECT Json_Locate_All('[[45,28],36,45,89]',45);
Json_Locate_All('[[45,28],36,45,89]',45)
["[0]:[0]","[2]"]
SELECT Json_Locate_All('[[45,28,45],36,45,89]',45);
Json_Locate_All('[[45,28,45],36,45,89]',45)
["[0]:[0]","[0]:[2]","[2]"]
SELECT Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'));
Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'))
["[0]:[0]","[0]:[2]","[2]"]
SELECT JsonLocate('[[45,28,45],36,45,89]',45,n) from t1;
JsonLocate('[[45,28,45],36,45,89]',45,n)
[0]:[0]
[0]:[2]
[2]
NULL
NULL
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) FROM t1;
JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']'))
[0]:[0]
[0]:[2]
[2]
NULL
NULL
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) AS `Path` FROM t1 GROUP BY n HAVING `Path` IS NOT NULL;
Path
[0]:[0]
[0]:[2]
[2]
SELECT Json_Locate_All('[45,28,[36,45,89]]',45);
Json_Locate_All('[45,28,[36,45,89]]',45)
["[0]","[2]:[1]"]
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0));
Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0))
[]
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',45.0);
Json_Locate_All('[[45,28],[36,45.0,89]]',45.0)
["[1]:[1]"]
SELECT JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_);
JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_)
[1]
SELECT JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_);
JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_)
[0]
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','45') "All paths";
All paths
[]
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_);
Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_)
["[1]:[0]"]
SELECT JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";
Nb of occurs
2
SELECT Json_Locate_All('[[45,28],[[36,45],89]]',45,2);
Json_Locate_All('[[45,28],[[36,45],89]]',45,2)
["[0]:[0]"]
SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]');
JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]')
[0]
SELECT JsonLocate(Json_File('test/biblio.json'), 'Knab');
JsonLocate(Json_File('test/biblio.json'), 'Knab')
[0]:AUTHOR:[1]:LASTNAME
SELECT Json_Locate_All('test/biblio.json' jfile_, 'Knab');
Json_Locate_All('test/biblio.json' jfile_, 'Knab')
["[0]:AUTHOR:[1]:LASTNAME"]
#
# Testing json files
#
SELECT Jfile_Make('[{"_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]}]', 'test/fx.json', 0) AS NewFile;
NewFile
test/fx.json
SELECT Jfile_Make('test/fx.json', 1);
Jfile_Make('test/fx.json', 1)
test/fx.json
SELECT Jfile_Make('test/fx.json' jfile_);
Jfile_Make('test/fx.json' jfile_)
test/fx.json
SELECT Jfile_Make(Jbin_File('test/fx.json'), 0);
Jfile_Make(Jbin_File('test/fx.json'), 0)
test/fx.json
SELECT Json_File('test/fx.json', 1);
Json_File('test/fx.json', 1)
[{"_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]}]
Warnings:
Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('test/fx.json', 2);
Json_File('test/fx.json', 2)
[{"_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]}]
Warnings:
Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('test/fx.json', 0);
Json_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 Json_File('test/fx.json', '[0]');
Json_File('test/fx.json', '[0]')
{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]}
SELECT Json_File('test/fx.json', '[?]');
Json_File('test/fx.json', '[?]')
NULL
Warnings:
Warning 1105 Invalid function specification ?
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]:*');
JsonGet_String(Json_File('test/fx.json'), '[1]:*')
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]}
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
JsonGet_String(Json_File('test/fx.json'), '[1]')
6 car roadster 56000 ???
SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
Mileage
56000
SELECT JsonGet_Real(Json_File('test/fx.json'), '[0]:price', 2) AS Price;
Price
5.65
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings');
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4,6]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings');
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1);
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1)
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0);
Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0)
[6,2,4]
SELECT Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1);
Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1)
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2]}
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin);
Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin)
{"_id":7,"type":"food","item":"meat","origin":"france","ratings":[2,4]}
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size');
Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]}
Warnings:
Warning 1105 No sub-item at 'size'
SELECT Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size');
Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size')
{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":70},"ratings":[5,8,7]}
SELECT Json_Object_List(Json_File('test/fx.json', '[3]:size'));
Json_Object_List(Json_File('test/fx.json', '[3]:size'))
["W","L","H"]
DROP TABLE t1;
DROP FUNCTION Json_Array;
DROP FUNCTION Json_Array_Add;
DROP FUNCTION Json_Object;
DROP FUNCTION Json_Object_Nonull;
DROP FUNCTION Json_Value;
DROP FUNCTION Json_Array_Grp;
DROP FUNCTION Json_Object_Grp;
DROP TABLE t2;
DROP TABLE t3;

View File

@@ -0,0 +1,588 @@
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=VIR BLOCK_SIZE=3;
#
# Test Jbin UDF's
#
SELECT Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), n) from t1;
Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), n)
[56,3.141600,"My name is \"Foo\"",null,1]
[56,3.141600,"My name is \"Foo\"",null,2]
[56,3.141600,"My name is \"Foo\"",null,3]
SELECT Json_Array_Add(Jbin_Array(n, 3.1416, 'My name is "Foo"', NULL), n) from t1;
Json_Array_Add(Jbin_Array(n, 3.1416, 'My name is "Foo"', NULL), n)
[1,3.141600,"My name is \"Foo\"",null,1]
[2,3.141600,"My name is \"Foo\"",null,2]
[3,3.141600,"My name is \"Foo\"",null,3]
SELECT Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), Jbin_Array('a','b',n)) from t1;
Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), Jbin_Array('a','b',n))
[56,3.141600,"My name is \"Foo\"",null,["a","b",1]]
[56,3.141600,"My name is \"Foo\"",null,["a","b",2]]
[56,3.141600,"My name is \"Foo\"",null,["a","b",3]]
SELECT Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), JsonGet_String(Jbin_Array('a','b','c'), '[1]'));
Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), JsonGet_String(Jbin_Array('a','b','c'), '[1]'))
[56,3.141600,"My name is \"Foo\"",null,"b"]
SELECT Json_Array_Delete(Jbin_Array_Add_Values(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), "One more", 2), 4);
Json_Array_Delete(Jbin_Array_Add_Values(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), "One more", 2), 4)
[56,3.141600,"My name is \"Foo\"",null,2]
SELECT Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), NULL), '[1]', 1);
Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), NULL), '[1]', 1)
[56,[3.141600],null]
SELECT Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), TRUE), 1, '[1]');
Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), TRUE), 1, '[1]')
[56,[3.141600],true]
SELECT Json_Array(1, TRUE, 0, FALSE);
Json_Array(1, TRUE, 0, FALSE)
[1,true,0,false]
SELECT Json_Serialize(Jbin_Array(TRUE, FALSE));
Json_Serialize(Jbin_Array(TRUE, FALSE))
[true,false]
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL);
Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL)
{"qty":56,"price":3.141600,"truc":"machin","garanty":null}
SELECT Json_Serialize(Jbin_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL));
Json_Serialize(Jbin_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL))
{"qty":56,"price":3.141600,"truc":"machin","garanty":null}
SELECT Jbin_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty');
ERROR HY000: Can't initialize function 'jbin_object_key'; This function must have an even number of arguments
SELECT Json_Object_Add(Jbin_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
Json_Object_Add(Jbin_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color)
{"qty":56,"price":3.141600,"truc":"machin","garanty":null,"color":"blue"}
SELECT Json_Object_Add(Jbin_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
Json_Object_Add(Jbin_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price)
{"qty":56,"price":45.990000,"truc":"machin","garanty":null}
SELECT Json_Object_Add(Jbin_Object_Nonull(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
Json_Object_Add(Jbin_Object_Nonull(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color)
{"qty":56,"price":3.141600,"truc":"machin","color":"blue"}
SELECT Json_Object_Add(Jbin_Object_Nonull(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
Json_Object_Add(Jbin_Object_Nonull(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price)
{"qty":56,"price":45.990000,"truc":"machin"}
#
# Test Jbin file UDF's
#
SELECT Json_Serialize(Jbin_File('gloss.json'));
Json_Serialize(Jbin_File('gloss.json'))
{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}
SELECT JsonLocate(Jbin_File('gloss.json'),'XML');
JsonLocate(Jbin_File('gloss.json'),'XML')
glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso:[1]
SELECT Json_Object_Key('first', 'foo', 'second', Jbin_Array('a', 33));
Json_Object_Key('first', 'foo', 'second', Jbin_Array('a', 33))
{"first":"foo","second":["a",33]}
SELECT Json_Get_Item(Json_Array('a','b','c'), '[1]');
Json_Get_Item(Json_Array('a','b','c'), '[1]')
NULL
SELECT Json_Get_Item(Json_Object('foo' AS "first", Json_Array('a', 33) AS "json_second"), 'second') AS "item";
item
["a",33]
SELECT Json_Get_Item(Jbin_Object('foo' first, Jbin_Array('a', 33) jbin_second), 'second:*') item;
item
["a",33]
SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv');
Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv')
{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}
SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv'));
Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv'))
{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}
SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:*');
Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:*')
{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}
SELECT JsonGet_String(Json_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso') lang;
lang
GML
SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso') "See also";
See also
["GML","XML"]
SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso')) "See also";
See also
["GML","XML"]
SELECT JsonGet_String(Json_Get_Item(Json_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso'),'[0]') lang;
lang
GML
#
# Test Item Get/Set/Insert/Update UDF's
#
SELECT Json_Get_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[]');
Json_Get_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[]')
[1,2,{"trois":3,"quatre":4}]
SELECT Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[1]');
Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[1]')
NULL
SELECT Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '[1]');
Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '[1]')
NULL
SELECT Json_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)));
Json_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)))
[1,2,{"trois":3,"quatre":4}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 'foo');
ERROR HY000: Can't initialize function 'json_set_item'; This function must have an odd number of arguments
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq')
[1,2,{"trois":3,"quatre":4,"cinq":5}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '[1]');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '[1]')
[1,7,{"trois":3,"quatre":4}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 7, '[1]');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 7, '[1]')
[1,7,{"trois":3,"quatre":4,"cinq":5}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Array(7, 8, 9), '[1]');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Array(7, 8, 9), '[1]')
[1,[7,8,9],{"trois":3,"quatre":4}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]')
[1,2,[7,8,9]]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]:*');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]:*')
[1,2,{"trois":3,"quatre":4}]
Warnings:
Warning 1105 Invalid specification * in a write path
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, 'foo');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, 'foo')
[1,2,{"trois":3,"quatre":4}]
SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '[1]:[2]');
Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '[1]:[2]')
[1,[7,8,"toto"],{"trois":3,"quatre":4}]
SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '[2]:nxt:total:[]');
Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '[2]:nxt:total:[]')
[1,[7,8,9],{"trois":3,"quatre":4,"nxt":{"total":[300]}}]
SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 300, '[2]:nxt:total:[]');
Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 300, '[2]:nxt:total:[]')
[1,[7,8,9,10],{"trois":3,"quatre":4,"cinq":5,"nxt":{"total":[300]}}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[1]', 5, '[2]:cinq', 10, '[1]:[]');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[1]', 5, '[2]:cinq', 10, '[1]:[]')
[1,[7,8,9,10],{"trois":3,"quatre":4,"cinq":5}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '[2]:quatre');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '[2]:quatre')
[1,2,{"trois":3,"quatre":44}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, 'truc');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, 'truc')
[1,2,{"trois":3,"quatre":4}]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '')
[1,2,{"trois":3,"quatre":4},5]
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '*');
Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '*')
[1,2,{"trois":3,"quatre":4}]
Warnings:
Warning 1105 Invalid specification * in a write path
SELECT Json_Serialize(Jbin_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq'));
Json_Serialize(Jbin_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq'))
[1,2,{"trois":3,"quatre":4,"cinq":5}]
SELECT Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq')
[1,2,{"trois":3,"quatre":4,"cinq":5}]
SELECT Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq')
[1,2,{"trois":3,"quatre":4}]
SELECT Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre');
Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre')
[1,[7,8,9,10],{"trois":3,"quatre":4,"cinq":5}]
SELECT Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre');
Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre')
[1,[7,8,9],{"trois":3,"quatre":44}]
SELECT Json_Insert_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]');
Json_Insert_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]')
[1,[7,8,9],{"trois":3,"quatre":4,"cinq":5,"nxt":{"total":[300]}}]
SELECT Json_Update_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]');
Json_Update_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]')
[1,[7,10,9],{"trois":3,"quatre":4}]
SELECT Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]');
Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]')
[1,2,{"trois":3,"quatre":4},5]
SELECT Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]');
Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]')
[1,2,{"trois":3,"quatre":4}]
#
# Test merging items UDF's
#
SELECT Json_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f'));
Json_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f'))
["a","b","c","d","e","f"]
SELECT Json_Item_Merge(Json_Array('a','b','c'), Json_Array('d','e','f')) AS "Result";
Result
["a","b","c","d","e","f"]
SELECT Json_Array_Add(Jbin_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f')), 'and', 3);
Json_Array_Add(Jbin_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f')), 'and', 3)
["a","b","c","and","d","e","f"]
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d",5 "e",6 "f"));
Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d",5 "e",6 "f"))
{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6}
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",2 "c"), Jbin_Array('d','e','f'));
Json_Item_Merge(Jbin_Object(1 "a",2 "b",2 "c"), Jbin_Array('d','e','f'))
Binary Json object
Warnings:
Warning 1105 Second argument is not an object
SELECT Json_Object_Add(Jbin_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d",5 "e",6 "f")), 'x' AS "and");
Json_Object_Add(Jbin_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d",5 "e",6 "f")), 'x' AS "and")
{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"and":"x"}
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "a",5 "e",6 "f"));
Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "a",5 "e",6 "f"))
{"a":4,"b":2,"c":3,"e":5,"f":6}
SELECT Json_Item_Merge('foo', Json_Array('d','e','f'));
ERROR HY000: Can't initialize function 'json_item_merge'; First argument must be a json item
#
# Test making file UDF's
#
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
SELECT Json_File('bt1.json');
Json_File('bt1.json')
[
"a",
"b",
"c"
]
SELECT Json_File(Jfile_Make(Jbin_File('bt1.json'), 0));
Json_File(Jfile_Make(Jbin_File('bt1.json'), 0))
"a"
"b"
"c"
SELECT Json_File(Jfile_Make(Jbin_File('bt1.json'), 1));
Json_File(Jfile_Make(Jbin_File('bt1.json'), 1))
[
"a",
"b",
"c"
]
SELECT Json_File(Jfile_Make(Jbin_File('bt1.json'), 2));
Json_File(Jfile_Make(Jbin_File('bt1.json'), 2))
[
"a",
"b",
"c"
]
SELECT Json_File('bt1.json', 0);
Json_File('bt1.json', 0)
["a","b","c"]
Warnings:
Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('bt1.json', 1);
Json_File('bt1.json', 1)
["a","b","c"]
Warnings:
Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('bt1.json', 2);
Json_File('bt1.json', 2)
["a","b","c"]
SELECT Json_Serialize(Jbin_Array('a','b','c'));
Json_Serialize(Jbin_Array('a','b','c'))
["a","b","c"]
SELECT Json_Serialize(Jbin_Array_Add(Jbin_File('not_exist.json'), 'd'));
Json_Serialize(Jbin_Array_Add(Jbin_File('not_exist.json'), 'd'))
Null json tree
Warnings:
Warning 1105 Open(map) error 2 on not_exist.json
Warning 1105 First argument is not an array
# This does not modify the file
SELECT Json_Serialize(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'));
Json_Serialize(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'))
["a","b","c","d"]
SELECT Json_File('bt1.json', 2);
Json_File('bt1.json', 2)
["a","b","c"]
# This does modify the file
SELECT Json_Array_Add(Jbin_File('bt1.json'), 'd');
Json_Array_Add(Jbin_File('bt1.json'), 'd')
bt1.json
SELECT Json_File('bt1.json', 2);
Json_File('bt1.json', 2)
["a","b","c","d"]
# Back to the original file
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
SELECT Json_Object(Jbin_Array_Add(Jbin_Array('a','b','c'), 'd') "Jbin_foo") AS "Result";
Result
{"foo":["a","b","c","d"]}
SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd')) AS "Result";
Result
{"Array_Add(Jbin_File('bt1.json'), 'd')":["a","b","c","d"]}
SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1") AS "Result";
Result
{"bt1":["a","b","c","d"]}
# This does modify the file
SELECT Json_Object(Json_Array_Add(Jbin_File('bt1.json'), 'd') "Jfile_bt1") AS "Result";
Result
{"bt1":["a","b","c","d"]}
SELECT Json_File('bt1.json');
Json_File('bt1.json')
[
"a",
"b",
"c",
"d"
]
SELECT Json_File(Json_Array_Delete(Jbin_File('bt1.json'), 3), 2);
Json_File(Json_Array_Delete(Jbin_File('bt1.json'), 3), 2)
["a","b","c"]
SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1", n "t1") AS "Result" from t1;
Result
{"bt1":["a","b","c","d"],"t1":1}
{"bt1":["a","b","c","d"],"t1":2}
{"bt1":["a","b","c","d"],"t1":3}
SELECT Json_File(Json_Array_Add(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'), 'e')) AS "Result";
Result
[
"a",
"b",
"c",
"d",
"e"
]
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
SELECT Json_File(Json_Array_Add(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'), 'e')) AS "Result" from t1;
Result
[
"a",
"b",
"c",
"d",
"e"
]
[
"a",
"b",
"c",
"d",
"e"
]
[
"a",
"b",
"c",
"d",
"e"
]
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
SELECT Json_Array_Add(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'), n) AS "Result" from t1;
Result
bt1.json
bt1.json
bt1.json
# Show modified file
SELECT Json_File('bt1.json');
Json_File('bt1.json')
[
"a",
"b",
"c",
"d",
1,
"d",
2,
"d",
3
]
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
SELECT Json_Array_Add(Jbin_File('bt1.json'), n) AS "Result" from t1;
Result
bt1.json
bt1.json
bt1.json
# Show modified file
SELECT Json_File('bt1.json');
Json_File('bt1.json')
[
"a",
"b",
"c",
1,
2,
3
]
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
SELECT Json_File(Jbin_Item_Merge(Jbin_File('bt1.json'), Jbin_Array('d','e','f')));
Json_File(Jbin_Item_Merge(Jbin_File('bt1.json'), Jbin_Array('d','e','f')))
[
"a",
"b",
"c"
]
SELECT Json_File(Json_Item_Merge(Jbin_File('bt1.json'), Jbin_Array('d','e','f')));
Json_File(Json_Item_Merge(Jbin_File('bt1.json'), Jbin_Array('d','e','f')))
[
"a",
"b",
"c",
"d",
"e",
"f"
]
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json')
bt1.json
# Test DELETE from file
SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 1)) AS "Result";
Result
{"Array_Delete(Jbin_File('bt1.json'), 1)":["a","c"]}
SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 2) "Jbin_bt1") AS "Result";
Result
{"bt1":["a","b"]}
SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 0) "Jbin_bt1", n "t1") AS "Result" from t1;
Result
{"bt1":["b","c"],"t1":1}
{"bt1":["b","c"],"t1":2}
{"bt1":["b","c"],"t1":3}
SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
Result
{"bt1":["a","b"]}
{"bt1":["a"]}
{"bt1":[]}
SELECT Json_Object(Json_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
Result
{"bt1":["a","b"]}
{"bt1":["a"]}
{"bt1":[]}
# Show modified file
SELECT Json_File('bt1.json');
Json_File('bt1.json')
[
]
# Object file
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0)
bt2.json
SELECT Json_File('bt2.json', 0);
Json_File('bt2.json', 0)
{"a":1,"b":2,"c":3}
SELECT Json_File('bt2.json');
Json_File('bt2.json')
{"a":1,"b":2,"c":3}
SELECT Json_Serialize(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"));
Json_Serialize(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"))
{"a":1,"b":2,"c":3,"d":4}
# First query (file not modified)
SELECT Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jbin_new") AS "Result";
Result
{"new":{"a":1,"b":2,"c":3,"d":4}}
# First query (file modified)
SELECT Json_Object(Json_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jfile_new") AS "Result";
Result
{"new":{"a":1,"b":2,"c":3,"d":4}}
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0)
bt2.json
SELECT Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d") "Jbin_new", n "t1") AS "Result" from t1;
Result
{"new":{"a":1,"b":2,"c":3,"d":4},"t1":1}
{"new":{"a":1,"b":2,"c":3,"d":4},"t1":2}
{"new":{"a":1,"b":2,"c":3,"d":4},"t1":3}
SELECT Json_File(Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), 5 "e")) AS "Result";
Result
{"a":1,"b":2,"c":3,"d":4,"e":5}
SELECT Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), 5 "e") AS "Result" from t1;
Result
bt2.json
bt2.json
bt2.json
SELECT Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), n "n") AS "Result" from t1;
Result
bt2.json
bt2.json
bt2.json
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0)
bt2.json
SELECT Json_Object_Add(Jbin_File('bt2.json'), n) AS "Result" from t1;
Result
bt2.json
bt2.json
bt2.json
SELECT Json_File('bt2.json');
Json_File('bt2.json')
{"a":1,"b":2,"c":3,"n":3}
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0)
bt2.json
SELECT Json_Serialize(Jbin_Item_Merge(Jbin_File('bt2.json'), Jbin_Object(4 "d",5 "e",6 "f"))) AS "Result";
Result
{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6}
SELECT Json_File(Json_Item_Merge(Jbin_File('bt2.json'), Jbin_Object(4 "d",5 "e",6 "f"))) AS "Result";
Result
{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6}
SELECT Json_Item_Merge(Json_Object(1 "a", 2 "b", 3 "c"), Json_Object(4 "d",5 "b",6 "f")) AS "Result";
Result
{"a":1,"b":5,"c":3,"d":4,"f":6}
SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'b')) AS "Result";
Result
{"Object_Delete(Jbin_File('bt2.json'), 'b')":{"a":1,"c":3,"d":4,"e":5,"f":6}}
SELECT Json_Object(Jbin_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
Result
{"bt1":{"a":1,"d":4,"e":5,"f":6}}
SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
Result
{"bt1":{"a":1,"d":4,"e":5,"f":6}}
SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jfile_bt1") AS "Result";
Result
{"bt1":{"a":1,"d":4,"e":5,"f":6}}
SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'a') "Jbin_bt1", n "t1") AS "Result" from t1;
Result
{"bt1":{"d":4,"e":5,"f":6},"t1":1}
{"bt1":{"d":4,"e":5,"f":6},"t1":2}
{"bt1":{"d":4,"e":5,"f":6},"t1":3}
SELECT Json_Serialize(Jbin_Object_List(Jbin_File('bt2.json'))) "Key list";
Key list
["d","e","f"]
SELECT Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0);
Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0)
bt3.json
SELECT Json_Array_Add(Json_File('bt3.json', 'b'), 66);
Json_Array_Add(Json_File('bt3.json', 'b'), 66)
[44,55,66]
SELECT Json_Array_Add(Json_File('bt3.json'), 66, 'b');
Json_Array_Add(Json_File('bt3.json'), 66, 'b')
{"a":1,"b":[44,55,66]}
SELECT Json_Array_Add(Jbin_File('bt3.json', 'b'), 66);
Json_Array_Add(Jbin_File('bt3.json', 'b'), 66)
bt3.json
SELECT Json_File('bt3.json', 3);
Json_File('bt3.json', 3)
{"a":1,"b":[44,55,66]}
SELECT Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0);
Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0)
bt3.json
CREATE TABLE t2 (
n INT KEY,
jfile_cols CHAR(12) NOT NULL)
ENGINE= MYISAM;
INSERT INTO t2 VALUES(1,'bt3.json');
# In this table, the jfile_cols column just contains a file name
UPDATE t2 SET jfile_cols = Json_Array_Add(Jbin_File('bt3.json', 'b'), 66) WHERE n = 1;
SELECT JsonGet_String(jfile_cols, '*') FROM t2;
JsonGet_String(jfile_cols, '*')
{"a":1,"b":[44,55,66]}
UPDATE t2 SET jfile_cols = Json_Insert_Item(jfile_cols, 77, 'b:[]') WHERE n = 1;
SELECT JsonGet_String(jfile_cols, 'b:*') FROM t2;
JsonGet_String(jfile_cols, 'b:*')
[44,55,66,77]
UPDATE t2 SET jfile_cols = Json_Insert_Item(Jbin_Insert_Item(jfile_cols, 88, 'b:') , 99, 'b:') WHERE n = 1;
SELECT JsonGet_String(jfile_cols, '*') FROM t2;
JsonGet_String(jfile_cols, '*')
{"a":1,"b":[44,55,66,77,88,99]}
DROP TABLE t1, t2;

View File

@@ -1,8 +1,10 @@
#
# Testing FILE privilege
#
set sql_mode="";
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
set sql_mode=default;
SELECT user();
user()
user@localhost
@@ -40,7 +42,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost

View File

@@ -49,10 +49,11 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
# using SQL SECIRITY INVOKER
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
@@ -64,6 +65,19 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
# using SQL SECIRITY DEFINER
DROP VIEW v1;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
SELECT * FROM v1 WHERE a='test1';
a
test1
SELECT user();
user()
root@localhost

View File

@@ -3,6 +3,7 @@ Warning 1105 No file name. Table will use t1.xml
#
# Beginning of grant.inc
#
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
SELECT user();
@@ -63,7 +64,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost

View File

@@ -0,0 +1,2 @@
{"ISBN":"9782212090819","LANG":"fr","SUBJECT":"applications","AUTHOR":[{"FIRSTNAME":"Jean-Michel","LASTNAME":"Bernadac"},{"FIRSTNAME":"Fran<61>ois","LASTNAME":"Knab"}],"TITLE":"Construire une application XML","PUBLISHER":{"NAME":"Eyrolles","PLACE":"Paris"},"DATEPUB":1999}
{"ISBN":"9782840825685","LANG":"fr","SUBJECT":"applications","AUTHOR":[{"FIRSTNAME":"William J.","LASTNAME":"Pardi"}],"TITLE":"XML en Action","TRANSLATED":{"PREFIX":"adapt<70> de l'anglais par","TRANSLATOR":{"FIRSTNAME":"James","LASTNAME":"Guerin"}},"PUBLISHER":{"NAME":"Microsoft Press","PLACE":"Paris"},"DATEPUB":2001}

View File

@@ -24,12 +24,10 @@
"ISBN": "9782840825685",
"LANG": "fr",
"SUBJECT": "applications",
"AUTHOR": [
{
"FIRSTNAME": "William J.",
"LASTNAME": "Pardi"
}
],
"AUTHOR": {
"FIRSTNAME": "William J.",
"LASTNAME": "Pardi"
},
"TITLE": "XML en Action",
"TRANSLATION": "adapt<70> de l'anglais par",
"TRANSLATOR": {

View File

@@ -0,0 +1,22 @@
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}

View File

@@ -14,3 +14,15 @@ SELECT id, DAYNAME(dat) FROM t1;
SELECT id, DAYNAME(datim) FROM t1 LIMIT 1;
SELECT id, TIME(tim) FROM t1 LIMIT 1;
DROP TABLE t1;
--echo #
--echo # Testing use of dates in where clause (MDEV-8926)
--echo #
CREATE TABLE t1 (col1 DATE) ENGINE=CONNECT TABLE_TYPE=CSV;
INSERT INTO t1 VALUES('2015-01-01'),('2015-02-01'),('2015-03-01'),('2015-04-01');
SELECT * FROM t1 WHERE col1 = '2015-02-01';
SELECT * FROM t1 WHERE col1 > '2015-02-01';
SELECT * FROM t1 WHERE col1 >= '2015-02-01';
SELECT * FROM t1 WHERE col1 < '2015-02-01';
SELECT * FROM t1 WHERE col1 <= '2015-02-01';
DROP TABLE t1;

View File

@@ -1,6 +1,7 @@
--echo #
--echo # Beginning of grant.inc
--echo #
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
--connect(user,localhost,user,,)
@@ -53,7 +54,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR

View File

@@ -1,4 +1,5 @@
-- source include/not_embedded.inc
set sql_mode="";
let $MYSQLD_DATADIR= `select @@datadir`;
@@ -49,7 +50,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
@@ -92,4 +93,4 @@ let $TABLE_OPTIONS=TABLE_TYPE=VEC MAX_ROWS=100;
let $FILE_EXT=VEC;
--source grant.inc
set sql_mode=default;

View File

@@ -5,8 +5,10 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--echo #
--echo # Checking FILE privileges
--echo #
set sql_mode="";
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
set sql_mode=default;
--connect(user,localhost,user,,)
--connection user
SELECT user();
@@ -54,7 +56,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR

View File

@@ -4,6 +4,7 @@
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/biblio.json $MYSQLD_DATADIR/test/biblio.json
--copy_file $MTR_SUITE_DIR/std_data/bib0.json $MYSQLD_DATADIR/test/bib0.json
--copy_file $MTR_SUITE_DIR/std_data/expense.json $MYSQLD_DATADIR/test/expense.json
--copy_file $MTR_SUITE_DIR/std_data/mulexp3.json $MYSQLD_DATADIR/test/mulexp3.json
--copy_file $MTR_SUITE_DIR/std_data/mulexp4.json $MYSQLD_DATADIR/test/mulexp4.json
@@ -115,6 +116,33 @@ ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='biblio.json';
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Testing a pretty=0 file
--echo #
CREATE TABLE t1
(
ISBN CHAR(15) NOT NULL,
Language CHAR(2) FIELD_FORMAT='LANG',
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
Title CHAR(32) FIELD_FORMAT='TITLE',
Translation CHAR(32) FIELD_FORMAT='TRANSLATED:PREFIX',
TranslatorFN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:FIRSTNAME',
TranslatorLN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:LASTNAME',
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
Year int(4) FIELD_FORMAT='DATEPUB',
INDEX IX(ISBN)
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bib0.json' LRECL=320 OPTION_LIST='Pretty=0';
SHOW INDEX FROM t1;
SELECT * FROM t1;
DESCRIBE SELECT * FROM t1 WHERE ISBN = '9782212090819';
--error ER_GET_ERRMSG
UPDATE t1 SET AuthorFN = 'Philippe' WHERE ISBN = '9782212090819';
DROP TABLE t1;
--echo #
--echo # A file with 2 arrays
--echo #
@@ -258,6 +286,8 @@ DROP TABLE t1, t2, t3, t4;
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/biblio.json
--remove_file $MYSQLD_DATADIR/test/bib0.dnx
--remove_file $MYSQLD_DATADIR/test/bib0.json
--remove_file $MYSQLD_DATADIR/test/expense.json
--remove_file $MYSQLD_DATADIR/test/mulexp3.json
--remove_file $MYSQLD_DATADIR/test/mulexp4.json

View File

@@ -9,28 +9,50 @@ if (!$HA_CONNECT_SO) {
--skip Needs a dynamically built ha_connect.so
}
let $is_win = `select convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows")`;
--eval CREATE FUNCTION json_array RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_array_add RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_array_add_values RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_array_delete RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object_nonull RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object_key RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object_add RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object_delete RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_object_list RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jsonvalue RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE AGGREGATE FUNCTION json_array_grp RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE AGGREGATE FUNCTION json_object_grp RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jsonget_string RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jsonget_int RETURNS INTEGER SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jsonget_real RETURNS REAL SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jsonlocate RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_locate_all RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_file RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jfile_make RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jsoncontains RETURNS INTEGER SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jsoncontains_path RETURNS INTEGER SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_get_item RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_set_item RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_insert_item RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_update_item RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_item_merge RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION json_serialize RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_array RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_array_add_values RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_array_add RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_array_delete RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_object RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_object_nonull RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_object_key RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_object_add RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_object_delete RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_object_list RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_get_item RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_item_merge RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_set_item RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_insert_item RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_update_item RETURNS STRING SONAME '$HA_CONNECT_SO';
--eval CREATE FUNCTION jbin_file RETURNS STRING SONAME '$HA_CONNECT_SO';
if ($is_win)
{
--eval CREATE FUNCTION Json_Array RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE FUNCTION Json_Array_Add RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE FUNCTION Json_Object RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE FUNCTION Json_Object_Nonull RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE FUNCTION Json_Value returns STRING SONAME 'ha_connect.dll';
--eval CREATE AGGREGATE FUNCTION Json_Array_Grp RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE AGGREGATE FUNCTION Json_Object_Grp RETURNS STRING SONAME 'ha_connect.dll';
}
if (!$is_win)
{
--eval CREATE FUNCTION Json_Array RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE FUNCTION Json_Array_Add RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE FUNCTION Json_Object RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE FUNCTION Json_Object_Nonull RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE FUNCTION Json_Value returns STRING SONAME 'ha_connect.so';
--eval CREATE AGGREGATE FUNCTION Json_Array_Grp RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE AGGREGATE FUNCTION Json_Object_Grp RETURNS STRING SONAME 'ha_connect.so';
}
--enable_query_log

View File

@@ -5,35 +5,78 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/biblio.json $MYSQLD_DATADIR/test/biblio.json
--copy_file $MTR_SUITE_DIR/std_data/employee.dat $MYSQLD_DATADIR/test/employee.dat
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=VIR BLOCK_SIZE=5;
--echo #
--echo # Test UDF's with constant arguments
--echo #
--error ER_CANT_INITIALIZE_UDF
SELECT JsonValue(56, 3.1416, 'foo', NULL);
SELECT JsonValue(3.1416);
SELECT JsonValue(-80);
SELECT JsonValue('foo');
SELECT JsonValue(9223372036854775807);
SELECT JsonValue(NULL);
SELECT JsonValue(TRUE);
SELECT JsonValue(FALSE);
SELECT JsonValue();
SELECT JsonValue('[11, 22, 33]' json_) FROM t1;
#
SELECT Json_Array();
SELECT Json_Object(56,3.1416,'foo',NULL);
SELECT Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty);
SELECT Json_Array(56,3.1416,'My name is "Foo"',NULL);
SELECT Json_Array(56, 3.1416, 'My name is "Foo"', NULL);
SELECT Json_Array(Json_Array(56, 3.1416, 'foo'), TRUE);
#
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL)) Array;
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL),'One more') Array;
SELECT Json_Array_Add(Json_Value('one value'),'One more');
SELECT Json_Array_Add(Json_Array(56, 3.1416, 'foo', NULL)) Array;
SELECT Json_Array_Add(Json_Array(56, 3.1416, 'foo', NULL), 'One more') Array;
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add('one value','One more');
SELECT Json_Array_Add('one value' json_,'One more');
SELECT Json_Array_Add(JsonValue('one value'), 'One more');
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Value(56,3.1416,'foo',NULL);
SELECT Json_Value(3.1416);
SELECT Json_Value('foo');
SELECT Json_Value(NULL);
SELECT Json_Value();
SELECT Json_Array_Add('one value', 'One more');
SELECT Json_Array_Add('one value' json_, 'One more');
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(5 json_, 'One more');
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 9);
SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), '[2]', 33, 1);
SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, '[2]', 1);
SELECT Json_Array_Add(Json_Array(1, 2, Json_Array(11, 22)), 33, 1, '[2]');
#
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), n) Array FROM t1;
SELECT Json_Array_Add_Values(Json_Array(n, 3.1416, 'machin'), n) Array FROM t1;
SELECT Json_Array_Add_Values('[56]', 3.1416, 'machin') Array;
#
SELECT Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), 0);
SELECT Json_Array_Delete(Json_Object(56, 3.1416, 'My name is Foo', NULL), 2);
SELECT Json_Array_Delete(Json_Array(56, 3.1416, 'My name is "Foo"', NULL), '2');
SELECT Json_Array_Delete(json_array(56, 3.1416, 'My name is "Foo"', NULL), '2', 2);
#
SELECT Json_Object(56, 3.1416, 'foo', NULL);
SELECT Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
SELECT Json_Object();
SELECT Json_Object(Json_Array(56,3.1416,'foo'),NULL);
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL);
SELECT Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL);
SELECT Json_Object(Json_Array(56, 3.1416, 'foo'), NULL);
SELECT Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL);
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty');
#
SELECT Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
SELECT Json_Object_Add(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
SELECT Json_Object_Add(Json_File('notexist.json'), 'cheese' item, '[1]', 1);
#
SELECT Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'truc');
SELECT Json_Object_Delete(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'chose');
#
SELECT Json_Object_List(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty)) "Key List";
SELECT Json_Object_List('{"qty":56, "price":3.1416, "truc":"machin", "garanty":null}') "Key List";
--echo #
--echo # Test UDF's with column arguments
--echo #
CREATE TABLE t1
CREATE TABLE t2
(
ISBN CHAR(15),
LANG CHAR(2),
@@ -46,14 +89,13 @@ CREATE TABLE t1
DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t1;
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t1;
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t1;
SELECT Json_Array_Grp(TITLE) FROM t1;
DROP TABLE t1;
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t2;
SELECT Json_Array_Grp(TITLE) FROM t2;
CREATE TABLE t1 (
CREATE TABLE t3 (
SERIALNO CHAR(5) NOT NULL,
NAME VARCHAR(12) NOT NULL FLAG=6,
SEX SMALLINT(1) NOT NULL,
@@ -64,30 +106,160 @@ CREATE TABLE t1 (
SALARY DOUBLE(8,2) NOT NULL FLAG=52
) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1;
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t1 WHERE NAME = 'MERCHANT';
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t1 GROUP BY DEPARTMENT;
set connect_json_grp_size=30;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT, TITLE;
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT;
SET connect_json_grp_size=30;
SELECT Json_Object(title, Json_Array_Grp(name) `json_names`) from t3 GROUP BY title;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Object_Grp(SALARY) FROM t1;
SELECT Json_Object_Grp(SALARY, NAME) FROM t1;
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t1 GROUP BY DEPARTMENT;
SELECT Json_Array_Grp(NAME) from t1;
DROP TABLE t1;
SELECT Json_Object_Grp(SALARY) FROM t3;
SELECT Json_Object_Grp(NAME, SALARY) FROM t3;
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(NAME, SALARY) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Array_Grp(NAME) FROM t3;
#
SELECT Json_Object_Key(name, title) FROM t3 WHERE DEPARTMENT = 318;
SELECT Json_Object_Grp(name, title) FROM t3 WHERE DEPARTMENT = 318;
DROP FUNCTION Json_Array;
DROP FUNCTION Json_Array_Add;
DROP FUNCTION Json_Object;
DROP FUNCTION Json_Object_Nonull;
DROP FUNCTION Json_Value;
DROP FUNCTION Json_Array_Grp;
DROP FUNCTION Json_Object_Grp;
--echo #
--echo # Test value getting UDF's
--echo #
SELECT JsonGet_String(Json_Array_Grp(name),'[#]') FROM t3;
SELECT JsonGet_String(Json_Array_Grp(name),'[","]') FROM t3;
SELECT JsonGet_String(Json_Array_Grp(name),'[>]') FROM t3;
SET @j1 = '[45,28,36,45,89]';
SELECT JsonGet_String(@j1,'[1]');
SELECT JsonGet_String(@j1 json_,'[3]');
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'[3]');
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Array(45,28,36,45,89),'[+]') "sum";
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*');
SELECT JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
SET @j2 = '{"qty":56,"price":3.141600,"truc":"machin","garanty":null}';
SELECT JsonGet_String(@j2 json_,'truc');
SELECT JsonGet_String(@j2,'truc');
SELECT JsonGet_String(@j2,'chose');
SELECT JsonGet_String(NULL json_, NULL);
SELECT department, JsonGet_String(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
#
SELECT JsonGet_Int(@j1, '[4]');
SELECT JsonGet_Int(@j1, '[#]');
SELECT JsonGet_Int(@j1, '[+]');
SELECT JsonGet_Int(@j1 json_, '[3]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '[3]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '["+"]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89), '[+]');
SELECT JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]');
SELECT JsonGet_Int(Json_Array(json_array(45,28), json_array(36,45,89)), '[0]:[1]');
SELECT JsonGet_Int(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'qty');
SELECT JsonGet_Int(@j2 json_, 'price');
SELECT JsonGet_Int(@j2, 'qty');
SELECT JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose');
SELECT JsonGet_Int(JsonGet_String(Json_Array(Json_Array(45,28),Json_Array(36,45,89)), '[1]:*'), '[+]') sum;
SELECT department, JsonGet_Int(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"), 'salaries:[+]') Sumsal FROM t3 GROUP BY department;
#
SELECT JsonGet_Real(@j1, '[2]');
SELECT JsonGet_Real(@j1 json_, '[3]', 2);
SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[3]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '["+"]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[+]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89), '[!]');
SELECT JsonGet_Real(Json_Array(json_array(45,28), json_array(36,45,89)), '[1]:[0]');
SELECT JsonGet_Real(Json_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'price');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_, 'qty');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'price');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'price', 4);
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}', 'chose');
SELECT department, JsonGet_Real(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
--echo #
--echo # Documentation examples
--echo #
SELECT
JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";
SELECT
JsonGet_String('{"qty":7,"price":29.50,"garanty":null}', 'price') "String",
JsonGet_Int('{"qty":7,"price":29.50,"garanty":null}', 'price') "Int",
JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}', 'price') "Real";
SELECT JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}', 'price', 3) "Real";
--echo #
--echo # Testing Locate
--echo #
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'jack' ci) Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"Jack", "LN":"London"}' json_) Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"jack", "LN":"London"}' json_) Path;
SELECT JsonLocate('[45,28,36,45,89]',36);
SELECT JsonLocate('[45,28,36,45,89]' json_,28.0);
SELECT Json_Locate_All('[45,28,36,45,89]',10);
SELECT Json_Locate_All('[45,28,36,45,89]',45);
SELECT Json_Locate_All('[[45,28],36,45,89]',45);
SELECT Json_Locate_All('[[45,28,45],36,45,89]',45);
SELECT Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'));
SELECT JsonLocate('[[45,28,45],36,45,89]',45,n) from t1;
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) FROM t1;
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) AS `Path` FROM t1 GROUP BY n HAVING `Path` IS NOT NULL;
SELECT Json_Locate_All('[45,28,[36,45,89]]',45);
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0));
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',45.0);
SELECT JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_);
SELECT JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_);
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','45') "All paths";
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_);
SELECT JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";
SELECT Json_Locate_All('[[45,28],[[36,45],89]]',45,2);
SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]');
SELECT JsonLocate(Json_File('test/biblio.json'), 'Knab');
SELECT Json_Locate_All('test/biblio.json' jfile_, 'Knab');
--echo #
--echo # Testing json files
--echo #
SELECT Jfile_Make('[{"_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]}]', 'test/fx.json', 0) AS NewFile;
SELECT Jfile_Make('test/fx.json', 1);
SELECT Jfile_Make('test/fx.json' jfile_);
SELECT Jfile_Make(Jbin_File('test/fx.json'), 0);
SELECT Json_File('test/fx.json', 1);
SELECT Json_File('test/fx.json', 2);
SELECT Json_File('test/fx.json', 0);
SELECT Json_File('test/fx.json', '[0]');
SELECT Json_File('test/fx.json', '[?]');
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]:*');
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
SELECT JsonGet_Real(Json_File('test/fx.json'), '[0]:price', 2) AS Price;
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings');
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings');
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1);
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0);
SELECT Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1);
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin);
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size');
SELECT Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size');
SELECT Json_Object_List(Json_File('test/fx.json', '[3]:size'));
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
#
# Clean up
#
--source json_udf2.inc
--remove_file $MYSQLD_DATADIR/test/biblio.json
--remove_file $MYSQLD_DATADIR/test/employee.dat
--remove_file $MYSQLD_DATADIR/test/fx.json

View File

@@ -0,0 +1,49 @@
--disable_query_log
DROP FUNCTION json_array;
DROP FUNCTION json_array_add;
DROP FUNCTION json_array_add_values;
DROP FUNCTION json_array_delete;
DROP FUNCTION json_object;
DROP FUNCTION json_object_nonull;
DROP FUNCTION json_object_key;
DROP FUNCTION json_object_add;
DROP FUNCTION json_object_delete;
DROP FUNCTION json_object_list;
DROP FUNCTION jsonvalue;
DROP FUNCTION json_array_grp;
DROP FUNCTION json_object_grp;
DROP FUNCTION jsonget_string;
DROP FUNCTION jsonget_int;
DROP FUNCTION jsonget_real;
DROP FUNCTION jsonlocate;
DROP FUNCTION json_locate_all;
DROP FUNCTION json_file;
DROP FUNCTION jfile_make;
DROP FUNCTION json_get_item;
DROP FUNCTION json_item_merge;
DROP FUNCTION jsoncontains;
DROP FUNCTION jsoncontains_path;
DROP FUNCTION json_set_item;
DROP FUNCTION json_insert_item;
DROP FUNCTION json_update_item;
DROP FUNCTION json_serialize;
DROP FUNCTION jbin_array;
DROP FUNCTION jbin_array_add_values;
DROP FUNCTION jbin_array_add;
DROP FUNCTION jbin_array_delete;
DROP FUNCTION jbin_object;
DROP FUNCTION jbin_object_nonull;
DROP FUNCTION jbin_object_key;
DROP FUNCTION jbin_object_add;
DROP FUNCTION jbin_object_delete;
DROP FUNCTION jbin_object_list;
DROP FUNCTION jbin_get_item;
DROP FUNCTION jbin_item_merge;
DROP FUNCTION jbin_set_item;
DROP FUNCTION jbin_insert_item;
DROP FUNCTION jbin_update_item;
DROP FUNCTION jbin_file;
--enable_query_log

View File

@@ -0,0 +1,212 @@
--source json_udf.inc
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/gloss.json $MYSQLD_DATADIR/gloss.json
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=VIR BLOCK_SIZE=3;
--echo #
--echo # Test Jbin UDF's
--echo #
SELECT Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), n) from t1;
SELECT Json_Array_Add(Jbin_Array(n, 3.1416, 'My name is "Foo"', NULL), n) from t1;
SELECT Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), Jbin_Array('a','b',n)) from t1;
SELECT Json_Array_Add(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), JsonGet_String(Jbin_Array('a','b','c'), '[1]'));
SELECT Json_Array_Delete(Jbin_Array_Add_Values(Jbin_Array(56, 3.1416, 'My name is "Foo"', NULL), "One more", 2), 4);
SELECT Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), NULL), '[1]', 1);
SELECT Json_Array_Delete(Jbin_Array(56, Jbin_Array(3.1416, 'My name is "Foo"'), TRUE), 1, '[1]');
SELECT Json_Array(1, TRUE, 0, FALSE);
SELECT Json_Serialize(Jbin_Array(TRUE, FALSE));
#
SELECT Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL);
SELECT Json_Serialize(Jbin_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL));
--error ER_CANT_INITIALIZE_UDF
SELECT Jbin_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty');
SELECT Json_Object_Add(Jbin_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
SELECT Json_Object_Add(Jbin_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
SELECT Json_Object_Add(Jbin_Object_Nonull(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 'blue' color);
SELECT Json_Object_Add(Jbin_Object_Nonull(56 qty, 3.1416 price, 'machin' truc, NULL garanty), 45.99 price);
--echo #
--echo # Test Jbin file UDF's
--echo #
SELECT Json_Serialize(Jbin_File('gloss.json'));
SELECT JsonLocate(Jbin_File('gloss.json'),'XML');
#
SELECT Json_Object_Key('first', 'foo', 'second', Jbin_Array('a', 33));
SELECT Json_Get_Item(Json_Array('a','b','c'), '[1]');
SELECT Json_Get_Item(Json_Object('foo' AS "first", Json_Array('a', 33) AS "json_second"), 'second') AS "item";
SELECT Json_Get_Item(Jbin_Object('foo' first, Jbin_Array('a', 33) jbin_second), 'second:*') item;
SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv');
SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv'));
SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:*');
SELECT JsonGet_String(Json_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso') lang;
SELECT Json_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso') "See also";
SELECT Json_Serialize(Jbin_Get_Item(Jbin_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso')) "See also";
SELECT JsonGet_String(Json_Get_Item(Json_File('gloss.json'),'glossary:GlossDiv:GlossList:GlossEntry:GlossDef:GlossSeeAlso'),'[0]') lang;
--echo #
--echo # Test Item Get/Set/Insert/Update UDF's
--echo #
SELECT Json_Get_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[]');
SELECT Json_Get_Item(Jbin_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), '[1]');
SELECT Json_Get_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), '[1]');
#
SELECT Json_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)));
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 'foo');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 7, '[1]');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 7, '[1]');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Json_Array(7, 8, 9), '[1]');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[2]:*');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 3.1416, 'foo');
SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 'toto', '[1]:[2]');
SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 300, '[2]:nxt:total:[]');
SELECT Json_Set_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 300, '[2]:nxt:total:[]');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), Jbin_Array(7, 8, 9), '[1]', 5, '[2]:cinq', 10, '[1]:[]');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 44, '[2]:quatre');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, 'truc');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '');
SELECT Json_Set_Item(Jbin_Array(1, 2, Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '*');
SELECT Json_Serialize(Jbin_Set_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq'));
#
SELECT Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
SELECT Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq');
SELECT Json_Insert_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre');
SELECT Json_Update_Item(Jbin_Array(1, Jbin_Array(7, 8, 9), Jbin_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[]', 44, '[2]:quatre');
SELECT Json_Insert_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]');
SELECT Json_Update_Item(Json_Array(1, Json_Array(7, 8, 9), Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[2]:cinq', 10, '[1]:[1]', 300, '[2]:nxt:total:[]');
SELECT Json_Insert_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]');
SELECT Json_Update_Item(Json_Array(1, 2, Json_Object_Key('trois', 3, 'quatre', 4)), 5, '[]');
--echo #
--echo # Test merging items UDF's
--echo #
SELECT Json_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f'));
SELECT Json_Item_Merge(Json_Array('a','b','c'), Json_Array('d','e','f')) AS "Result";
SELECT Json_Array_Add(Jbin_Item_Merge(Jbin_Array('a','b','c'), Jbin_Array('d','e','f')), 'and', 3);
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d",5 "e",6 "f"));
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",2 "c"), Jbin_Array('d','e','f'));
SELECT Json_Object_Add(Jbin_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "d",5 "e",6 "f")), 'x' AS "and");
SELECT Json_Item_Merge(Jbin_Object(1 "a",2 "b",3 "c"), Jbin_Object(4 "a",5 "e",6 "f"));
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Item_Merge('foo', Json_Array('d','e','f'));
--echo #
--echo # Test making file UDF's
--echo #
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
SELECT Json_File('bt1.json');
SELECT Json_File(Jfile_Make(Jbin_File('bt1.json'), 0));
SELECT Json_File(Jfile_Make(Jbin_File('bt1.json'), 1));
SELECT Json_File(Jfile_Make(Jbin_File('bt1.json'), 2));
SELECT Json_File('bt1.json', 0);
SELECT Json_File('bt1.json', 1);
SELECT Json_File('bt1.json', 2);
SELECT Json_Serialize(Jbin_Array('a','b','c'));
SELECT Json_Serialize(Jbin_Array_Add(Jbin_File('not_exist.json'), 'd'));
--echo # This does not modify the file
SELECT Json_Serialize(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'));
SELECT Json_File('bt1.json', 2);
--echo # This does modify the file
SELECT Json_Array_Add(Jbin_File('bt1.json'), 'd');
SELECT Json_File('bt1.json', 2);
--echo # Back to the original file
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
SELECT Json_Object(Jbin_Array_Add(Jbin_Array('a','b','c'), 'd') "Jbin_foo") AS "Result";
SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd')) AS "Result";
SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1") AS "Result";
--echo # This does modify the file
SELECT Json_Object(Json_Array_Add(Jbin_File('bt1.json'), 'd') "Jfile_bt1") AS "Result";
SELECT Json_File('bt1.json');
SELECT Json_File(Json_Array_Delete(Jbin_File('bt1.json'), 3), 2);
SELECT Json_Object(Jbin_Array_Add(Jbin_File('bt1.json'), 'd') "Jbin_bt1", n "t1") AS "Result" from t1;
SELECT Json_File(Json_Array_Add(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'), 'e')) AS "Result";
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
SELECT Json_File(Json_Array_Add(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'), 'e')) AS "Result" from t1;
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
SELECT Json_Array_Add(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'), n) AS "Result" from t1;
--echo # Show modified file
SELECT Json_File('bt1.json');
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
SELECT Json_Array_Add(Jbin_File('bt1.json'), n) AS "Result" from t1;
--echo # Show modified file
SELECT Json_File('bt1.json');
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
SELECT Json_File(Jbin_Item_Merge(Jbin_File('bt1.json'), Jbin_Array('d','e','f')));
SELECT Json_File(Json_Item_Merge(Jbin_File('bt1.json'), Jbin_Array('d','e','f')));
SELECT Jfile_Make(Jbin_Array('a','b','c'), 'bt1.json');
--echo # Test DELETE from file
SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 1)) AS "Result";
SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 2) "Jbin_bt1") AS "Result";
SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 0) "Jbin_bt1", n "t1") AS "Result" from t1;
SELECT Json_Object(Jbin_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
SELECT Json_Object(Json_Array_Delete(Jbin_File('bt1.json'), 3 - n) "Jbin_bt1") AS "Result" from t1;
--echo # Show modified file
SELECT Json_File('bt1.json');
--echo # Object file
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
SELECT Json_File('bt2.json', 0);
SELECT Json_File('bt2.json');
SELECT Json_Serialize(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"));
--echo # First query (file not modified)
SELECT Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jbin_new") AS "Result";
--echo # First query (file modified)
SELECT Json_Object(Json_Object_Add(Jbin_File('bt2.json'), 4 AS "d") AS "Jfile_new") AS "Result";
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
SELECT Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d") "Jbin_new", n "t1") AS "Result" from t1;
SELECT Json_File(Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), 5 "e")) AS "Result";
SELECT Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), 5 "e") AS "Result" from t1;
SELECT Json_Object_Add(Jbin_Object_Add(Jbin_File('bt2.json'), 4 "d"), n "n") AS "Result" from t1;
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
SELECT Json_Object_Add(Jbin_File('bt2.json'), n) AS "Result" from t1;
SELECT Json_File('bt2.json');
SELECT Jfile_Make(Jbin_Object(1 "a", 2 "b", 3 "c"), 'bt2.json', 0);
SELECT Json_Serialize(Jbin_Item_Merge(Jbin_File('bt2.json'), Jbin_Object(4 "d",5 "e",6 "f"))) AS "Result";
SELECT Json_File(Json_Item_Merge(Jbin_File('bt2.json'), Jbin_Object(4 "d",5 "e",6 "f"))) AS "Result";
SELECT Json_Item_Merge(Json_Object(1 "a", 2 "b", 3 "c"), Json_Object(4 "d",5 "b",6 "f")) AS "Result";
#
SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'b')) AS "Result";
SELECT Json_Object(Jbin_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jbin_bt1") AS "Result";
SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'c') "Jfile_bt1") AS "Result";
SELECT Json_Object(Json_Object_Delete(Jbin_File('bt2.json'), 'a') "Jbin_bt1", n "t1") AS "Result" from t1;
#
SELECT Json_Serialize(Jbin_Object_List(Jbin_File('bt2.json'))) "Key list";
#
# Test documentation examples
#
SELECT Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0);
SELECT Json_Array_Add(Json_File('bt3.json', 'b'), 66);
SELECT Json_Array_Add(Json_File('bt3.json'), 66, 'b');
SELECT Json_Array_Add(Jbin_File('bt3.json', 'b'), 66);
SELECT Json_File('bt3.json', 3);
SELECT Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'bt3.json', 0);
#
CREATE TABLE t2 (
n INT KEY,
jfile_cols CHAR(12) NOT NULL)
ENGINE= MYISAM;
INSERT INTO t2 VALUES(1,'bt3.json');
--echo # In this table, the jfile_cols column just contains a file name
UPDATE t2 SET jfile_cols = Json_Array_Add(Jbin_File('bt3.json', 'b'), 66) WHERE n = 1;
SELECT JsonGet_String(jfile_cols, '*') FROM t2;
UPDATE t2 SET jfile_cols = Json_Insert_Item(jfile_cols, 77, 'b:[]') WHERE n = 1;
SELECT JsonGet_String(jfile_cols, 'b:*') FROM t2;
UPDATE t2 SET jfile_cols = Json_Insert_Item(Jbin_Insert_Item(jfile_cols, 88, 'b:') , 99, 'b:') WHERE n = 1;
SELECT JsonGet_String(jfile_cols, '*') FROM t2;
DROP TABLE t1, t2;
#
# Clean up
#
--source json_udf2.inc
--remove_file $MYSQLD_DATADIR/gloss.json
--remove_file $MYSQLD_DATADIR/bt1.json
--remove_file $MYSQLD_DATADIR/bt2.json
--remove_file $MYSQLD_DATADIR/bt3.json

View File

@@ -19,8 +19,10 @@ DROP TABLE t1;
--echo #
--echo # Testing FILE privilege
--echo #
set sql_mode="";
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
set sql_mode=default;
--connect(user,localhost,user,,)
--connection user
SELECT user();
@@ -54,7 +56,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR

View File

@@ -27,6 +27,15 @@
#Servername=localhost
#Port=5432
#
# 5. Allow user "mtr" to connect to the database "mtr"
# Add this line into the begginning of pg_hba.conf
# (usually /var/lib/pgsql/data/pg_hba.conf on Linux):
#host mtr mtr 127.0.0.1/32 password
#
# 6. Restart the server:
# sudo service postgresql restart
#
#
SET NAMES utf8;

View File

@@ -56,9 +56,10 @@ ALTER TABLE t1 READONLY=1;
CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--echo # using SQL SECIRITY INVOKER
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
@@ -70,6 +71,17 @@ UPDATE v1 SET a=123;
--error ER_ACCESS_DENIED_ERROR
DELETE FROM v1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--echo # using SQL SECIRITY DEFINER
--connection default
DROP VIEW v1;
SELECT user();
CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
SELECT * FROM v1 WHERE a='test1';
--disconnect user
--connection default
SELECT user();

View File

@@ -143,7 +143,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
return NULL;
} else {
g->Sarea_Size = worksize;
g->Sarea = NULL;
g->Createas = 0;
g->Alchecked = 0;
g->Mrr = 0;
@@ -155,7 +155,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
/*******************************************************************/
/* Allocate the main work segment. */
/*******************************************************************/
if (!(g->Sarea = PlugAllocMem(g, worksize))) {
if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
char errmsg[256];
sprintf(errmsg, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg);
@@ -163,7 +163,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
} else
g->Sarea_Size = worksize;
} /* endif g */
} /* endif g */
g->jump_level = -1; /* New setting to allow recursive call of Plug */
return(g);

View File

@@ -47,6 +47,7 @@
#include "valblk.h"
#include "tabmul.h"
#include "ha_connect.h"
#include "mycat.h"
#if !defined(__WIN__)
extern handlerton *connect_hton;

View File

@@ -2019,7 +2019,7 @@ int TDBDOS::EstimatedLength(void)
dep = 1 + cdp->GetLong() / 20; // Why 20 ?????
} else for (; cdp; cdp = cdp->GetNext())
if (!(cdp->Flags & (U_VIRTUAL|U_SPECIAL)))
dep = MY_MAX(dep, cdp->GetOffset());
dep = MY_MAX(dep, cdp->GetOffset());
return (int)dep;
} // end of Estimated Length
@@ -2204,7 +2204,7 @@ bool TDBDOS::PrepareWriting(PGLOBAL)
} // endif Mode
return false;
} // end of WriteDB
} // end of PrepareWriting
/***********************************************************************/
/* WriteDB: Data Base write routine for DOS access method. */
@@ -2216,7 +2216,7 @@ int TDBDOS::WriteDB(PGLOBAL g)
// Make the line to write
if (PrepareWriting(g))
return true;
return RC_FX;
if (trace > 1)
htrc("Write: line is='%s'\n", To_Line);

View File

@@ -659,7 +659,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
if (!IsRead() && ((rc = ReadBuffer(g)) != RC_OK)) {
// Deferred reading failed
} else if (!(Row = ParseJson(g, To_Line,
strlen(To_Line), Pretty, &Comma))) {
strlen(To_Line), &Pretty, &Comma))) {
rc = (Pretty == 1 && !strcmp(To_Line, "]")) ? RC_EF : RC_FX;
} else {
Row = FindRow(g);
@@ -755,7 +755,6 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
} else
strcpy(To_Line, s);
// Row->Clear();
return false;
} else
return true;
@@ -980,7 +979,7 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
Nod = colp->Nod;
Nodes = colp->Nodes;
Xpd = colp->Xpd;
goto fin;
goto fin;
} // endif Name
sprintf(g->Message, "Cannot parse updated column %s", Name);
@@ -1046,7 +1045,8 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
switch (val->GetValType()) {
case TYPE_STRG:
case TYPE_INTG:
case TYPE_DBL:
case TYPE_BINT:
case TYPE_DBL:
vp->SetValue_pval(val->GetValue());
break;
case TYPE_BOOL:
@@ -1107,7 +1107,7 @@ PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
} else switch (row->GetType()) {
case TYPE_JOB:
if (!Nodes[i].Key) {
// Expected Array was not there
// Expected Array was not there, wrap the value
if (i < Nod-1)
continue;
else
@@ -1128,11 +1128,11 @@ PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
else
return CalculateArray(g, arp, i);
} else if (i < Nod-1) {
strcpy(g->Message, "Unexpected array");
val = NULL; // Not an expected array
} else
val = arp->GetValue(0);
} else {
// Unexpected array, unwrap it as [0]
val = arp->GetValue(0);
i--;
} // endif's
break;
case TYPE_JVAL:
@@ -1275,30 +1275,31 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
PJAR arp;
PJSON nwr, row = Tjp->Row;
for (int i = 0; i < Nod-1 && row; i++) {
if (Nodes[i+1].Op == OP_XX)
for (int i = 0; i < Nod && row; i++) {
if (Nodes[i+1].Op == OP_XX)
break;
else switch (row->GetType()) {
case TYPE_JOB:
if (!Nodes[i].Key)
// Expected Array was not there
// Expected Array was not there, wrap the value
continue;
val = ((PJOB)row)->GetValue(Nodes[i].Key);
break;
case TYPE_JAR:
if (!Nodes[i].Key) {
arp = (PJAR)row;
arp = (PJAR)row;
if (!Nodes[i].Key) {
if (Nodes[i].Op == OP_EQ)
val = arp->GetValue(Nodes[i].Rank);
else
val = arp->GetValue(Nodes[i].Rx);
} else {
strcpy(g->Message, "Unexpected array");
val = NULL; // Not an expected array
} // endif Nodes
// Unexpected array, unwrap it as [0]
val = arp->GetValue(0);
i--;
} // endif Nodes
break;
case TYPE_JVAL:
@@ -1353,7 +1354,7 @@ void JSONCOL::WriteColumn(PGLOBAL g)
longjmp(g->jumper[g->jump_level], 666);
} // endif Xpd
/*********************************************************************/
/*********************************************************************/
/* Check whether this node must be written. */
/*********************************************************************/
if (Value != To_Val)
@@ -1370,7 +1371,6 @@ void JSONCOL::WriteColumn(PGLOBAL g)
PJAR arp = NULL;
PJVAL jvp = NULL;
PJSON jsp, row = GetRow(g);
JTYP type = row->GetType();
switch (row->GetType()) {
case TYPE_JOB: objp = (PJOB)row; break;
@@ -1384,7 +1384,7 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (Nodes[Nod-1].Op == OP_XX) {
s = Value->GetCharValue();
if (!(jsp = ParseJson(g, s, (int)strlen(s), 0))) {
if (!(jsp = ParseJson(g, s, (int)strlen(s)))) {
strcpy(g->Message, s);
longjmp(g->jumper[g->jump_level], 666);
} // endif jsp
@@ -1522,7 +1522,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
/* Parse the json file and allocate its tree structure. */
/*********************************************************************/
g->Message[0] = 0;
jsp = Top = ParseJson(g, memory, len, Pretty);
jsp = Top = ParseJson(g, memory, len, &Pretty);
Txfp->CloseTableFile(g, false);
Mode = mode; // Restore saved Mode
@@ -1540,7 +1540,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
if (*objpath != '[') { // objpass is a key
if (jsp->GetType() != TYPE_JOB) {
strcpy(g->Message, "Table path does no match json file");
strcpy(g->Message, "Table path does not match the json file");
return RC_FX;
} // endif Type
@@ -1556,7 +1556,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
} else if (objpath[strlen(objpath)-1] == ']') {
if (jsp->GetType() != TYPE_JAR) {
strcpy(g->Message, "Table path does no match json file");
strcpy(g->Message, "Table path does not match the json file");
return RC_FX;
} // endif Type
@@ -1837,7 +1837,6 @@ void TDBJSON::CloseDB(PGLOBAL g)
// Save the modified document
char filename[_MAX_PATH];
PSZ msg;
FILE *fop;
Doc->InitArray(g);
@@ -1845,11 +1844,7 @@ void TDBJSON::CloseDB(PGLOBAL g)
PlugSetPath(filename, ((PJDEF)To_Def)->Fn, GetPath());
// Serialize the modified table
if (!(fop = fopen(filename, "wb"))) {
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"w", (int)errno, filename);
strcat(strcat(g->Message, ": "), strerror(errno));
} else if ((msg = Serialize(g, Top, fop, Pretty)))
if ((msg = Serialize(g, Top, filename, Pretty)))
puts(msg);
} // end of CloseDB

View File

@@ -1054,32 +1054,14 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
/***********************************************************************/
/* Data Base indexed read routine for MYSQL access method. */
/***********************************************************************/
bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
{
bool oom;
int oldlen = Query->GetLength();
PHC hc = To_Def->GetHandler();
if (op == OP_FIRST && hc->end_range) {
#ifdef _DEBUG
assert(!key);
#endif
key_range *end_key = &hc->save_end_range;
key = end_key->key;
len = end_key->length;
switch (end_key->flag) {
case HA_READ_BEFORE_KEY: op = OP_LT; break;
case HA_READ_AFTER_KEY: op = OP_LE; break;
default: key = NULL;
} // endswitch flag
} // endif OP_FIRST
if (!key || op == OP_NEXT ||
Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!key && Mode == MODE_READX) {
if (!(kr || hc->end_range) || op == OP_NEXT ||
Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!kr && Mode == MODE_READX) {
// This is a false indexed read
m_Rc = Myc.ExecSQL(g, Query->GetStr());
Mode = MODE_READ;
@@ -1091,23 +1073,35 @@ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
if (Myc.m_Res)
Myc.FreeResult();
if (hc->MakeKeyWhere(g, Query, op, '`', key, len))
if (hc->MakeKeyWhere(g, Query, op, '`', kr))
return true;
if (To_CondFil) {
oom = Query->Append(" AND (");
oom |= Query->Append(To_CondFil->Body);
if (To_CondFil->Idx != hc->active_index) {
To_CondFil->Idx = hc->active_index;
To_CondFil->Body= (char*)PlugSubAlloc(g, NULL, 0);
*To_CondFil->Body= 0;
if ((oom |= Query->Append(')'))) {
strcpy(g->Message, "Readkey: Out of memory");
return true;
} // endif oom
if ((To_CondFil = hc->CheckCond(g, To_CondFil, To_CondFil->Cond)))
PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
} // endif To_Condfil
} // endif active_index
} // endif's op
if (To_CondFil)
if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) {
strcpy(g->Message, "Readkey: Out of memory");
return true;
} // endif Append
m_Rc = Myc.ExecSQL(g, Query->GetStr());
} // endif To_Condfil
Mode = MODE_READ;
} // endif's op
if (trace)
htrc("MYSQL ReadKey: Query=%s\n", Query->GetStr());
m_Rc = Myc.ExecSQL(g, Query->GetStr());
Query->Truncate(oldlen);
return (m_Rc == RC_FX) ? true : false;
} // end of ReadKey

View File

@@ -99,7 +99,7 @@ class TDBMYSQL : public TDBASE {
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr);
// Specific routines
bool SetColumnRanks(PGLOBAL g);

View File

@@ -1,7 +1,7 @@
/************* Tabodbc C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABODBC */
/* ------------- */
/* Version 2.9 */
/* Version 3.0 */
/* */
/* COPYRIGHT: */
/* ---------- */
@@ -35,6 +35,7 @@
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
#include "sql_class.h"
#if defined(__WIN__)
#include <io.h>
#include <fcntl.h>
@@ -72,6 +73,7 @@
#include "reldef.h"
#include "tabcol.h"
#include "valblk.h"
#include "ha_connect.h"
#include "sql_string.h"
@@ -322,7 +324,7 @@ PSZ TDBODBC::GetFile(PGLOBAL g)
if (Connect) {
char *p1, *p2;
int i;
size_t n;
size_t n;
if (!(p1 = strstr(Connect, "DBQ="))) {
char *p, *lc = strlwr(PlugDup(g, Connect));
@@ -334,8 +336,8 @@ PSZ TDBODBC::GetFile(PGLOBAL g)
} else
i = 4;
if (p1) {
p1 += i; // Beginning of file name
if (p1) {
p1 += i; // Beginning of file name
p2 = strchr(p1, ';'); // End of file path/name
// Make the File path/name from the connect string
@@ -397,176 +399,209 @@ int TDBODBC::Decode(char *txt, char *buf, size_t n)
/* Note: when implementing EOM filtering, column only used in local */
/* filter should be removed from column list. */
/***********************************************************************/
char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
{
char *colist, *tabname, *sql, buf[NAM_LEN * 3];
LPCSTR schmp = NULL, catp = NULL;
int len, ncol = 0;
bool first = true;
PTABLE tablep = To_Table;
PCOL colp;
char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
int len;
bool oom = false, first = true;
PTABLE tablep = To_Table;
PCOL colp;
if (Srcdef)
return Srcdef;
if (Srcdef) {
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
if (!cnt) {
// Normal SQL statement to retrieve results
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial())
ncol++;
// Allocate the string used to contain the Query
Query = new(g)STRING(g, 1023, "SELECT ");
if (ncol) {
colist = (char*)PlugSubAlloc(g, NULL, (NAM_LEN + 4) * ncol);
if (!cnt) {
if (Columns) {
// Normal SQL statement to retrieve results
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
if (!first)
oom |= Query->Append(", ");
else
first = false;
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
// Column name can be in UTF-8 encoding
/*rc=*/ Decode(colp->GetName(), buf, sizeof(buf));
// Column name can be encoded in UTF-8
Decode(colp->GetName(), buf, sizeof(buf));
if (Quote) {
if (first) {
strcat(strcat(strcpy(colist, Quote), buf), Quote);
first = false;
} else
strcat(strcat(strcat(strcat(colist, ", "),
Quote), buf), Quote);
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
} else {
if (first) {
strcpy(colist, buf);
first = false;
} else
strcat(strcat(colist, ", "), buf);
} // endif colp
} // endif Quote
} // endif !Special
} else {
// ncol == 0 can occur for queries such that sql count(*) from...
} else
// !Columns can occur for queries such that sql count(*) from...
// for which we will count the rows from sql * from...
colist = (char*)PlugSubAlloc(g, NULL, 2);
strcpy(colist, "*");
} // endif ncol
oom |= Query->Append('*');
} else {
} else
// SQL statement used to retrieve the size of the result
colist = (char*)PlugSubAlloc(g, NULL, 9);
strcpy(colist, "count(*)");
} // endif cnt
oom |= Query->Append("count(*)");
// Table name can be encoded in UTF-8
/*rc = */Decode(TableName, buf, sizeof(buf));
// Put table name between identifier quotes in case in contains blanks
tabname = (char*)PlugSubAlloc(g, NULL, strlen(buf) + 3);
if (Quote)
strcat(strcat(strcpy(tabname, Quote), buf), Quote);
else
strcpy(tabname, buf);
// Below 14 is length of 'select ' + length of ' from ' + 1
len = (strlen(colist) + strlen(buf) + 14);
len += (To_CondFil ? strlen(To_CondFil->Body) + 7 : 0);
oom |= Query->Append(" FROM ");
if (Catalog && *Catalog)
catp = Catalog;
if (catp)
len += (strlen(catp) + 2);
if (tablep->GetSchema())
schmp = tablep->GetSchema();
schmp = (char*)tablep->GetSchema();
else if (Schema && *Schema)
schmp = Schema;
if (schmp)
len += (strlen(schmp) + 1);
sql = (char*)PlugSubAlloc(g, NULL, len);
strcat(strcat(strcpy(sql, "SELECT "), colist), " FROM ");
if (catp) {
strcat(sql, catp);
oom |= Query->Append(catp);
if (schmp)
strcat(strcat(sql, "."), schmp);
else
strcat(sql, ".");
if (schmp) {
oom |= Query->Append('.');
oom |= Query->Append(schmp);
} // endif schmp
strcat(sql, ".");
} else if (schmp)
strcat(strcat(sql, schmp), ".");
oom |= Query->Append('.');
} else if (schmp) {
oom |= Query->Append(schmp);
oom |= Query->Append('.');
} // endif schmp
strcat(sql, tabname);
// Table name can be encoded in UTF-8
Decode(TableName, buf, sizeof(buf));
if (To_CondFil)
strcat(strcat(sql, " WHERE "), To_CondFil->Body);
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
if (trace)
htrc("sql: '%s'\n", sql);
len = Query->GetLength();
return sql;
if (To_CondFil) {
if (Mode == MODE_READ) {
oom |= Query->Append(" WHERE ");
oom |= Query->Append(To_CondFil->Body);
len = Query->GetLength() + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
} else
len += ((Mode == MODE_READX) ? 256 : 1);
if (oom || Query->Resize(len)) {
strcpy(g->Message, "MakeSQL: Out of memory");
return true;
} // endif oom
if (trace)
htrc("Query=%s\n", Query->GetStr());
return false;
} // end of MakeSQL
/***********************************************************************/
/* MakeInsert: make the Insert statement used with ODBC connection. */
/***********************************************************************/
char *TDBODBC::MakeInsert(PGLOBAL g)
bool TDBODBC::MakeInsert(PGLOBAL g)
{
char *stmt, *colist, *valist, buf[NAM_LEN * 3];
// char *tk = "`";
int len = 0;
bool b = FALSE;
PCOL colp;
char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
int len = 0;
bool b = false, oom = false;
PTABLE tablep = To_Table;
PCOL colp;
for (colp = Columns; colp; colp = colp->GetNext())
if (colp->IsSpecial()) {
strcpy(g->Message, MSG(NO_ODBC_SPECOL));
return NULL;
return true;
} else {
len += (strlen(colp->GetName()) + 4);
// Column name can be encoded in UTF-8
Decode(colp->GetName(), buf, sizeof(buf));
len += (strlen(buf) + 6); // comma + quotes + valist
((PODBCCOL)colp)->Rank = ++Nparm;
} // endif colp
colist = (char*)PlugSubAlloc(g, NULL, len);
*colist = '\0';
valist = (char*)PlugSubAlloc(g, NULL, 2 * Nparm);
*valist = '\0';
// Below 32 is enough to contain the fixed part of the query
if (Catalog && *Catalog)
catp = Catalog;
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b) {
strcat(colist, ", ");
strcat(valist, ",");
} else
b = true;
if (catp)
len += strlen(catp) + 1;
// Column name can be in UTF-8 encoding
Decode(colp->GetName(), buf, sizeof(buf));
if (tablep->GetSchema())
schmp = (char*)tablep->GetSchema();
else if (Schema && *Schema)
schmp = Schema;
if (Quote)
strcat(strcat(strcat(colist, Quote), buf), Quote);
else
strcat(colist, buf);
if (schmp)
len += strlen(schmp) + 1;
strcat(valist, "?"); // Parameter marker
} // endfor colp
// Column name can be encoded in UTF-8
Decode(TableName, buf, sizeof(buf));
len += (strlen(buf) + 32);
Query = new(g) STRING(g, len, "INSERT INTO ");
// Below 32 is enough to contain the fixed part of the query
len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32);
stmt = (char*)PlugSubAlloc(g, NULL, len);
strcpy(stmt, "INSERT INTO ");
if (catp) {
oom |= Query->Append(catp);
if (Quote)
strcat(strcat(strcat(stmt, Quote), TableName), Quote);
else
strcat(stmt, TableName);
if (schmp) {
oom |= Query->Append('.');
oom |= Query->Append(schmp);
} // endif schmp
strcat(strcat(strcat(stmt, " ("), colist), ") VALUES (");
strcat(strcat(stmt, valist), ")");
oom |= Query->Append('.');
} else if (schmp) {
oom |= Query->Append(schmp);
oom |= Query->Append('.');
} // endif schmp
return stmt;
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
oom |= Query->Append('(');
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b)
oom |= Query->Append(", ");
else
b = true;
// Column name can be in UTF-8 encoding
Decode(colp->GetName(), buf, sizeof(buf));
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
} // endfor colp
oom |= Query->Append(") VALUES (");
for (int i = 0; i < Nparm; i++)
oom |= Query->Append("?,");
if (oom)
strcpy(g->Message, "MakeInsert: Out of memory");
else
Query->RepLast(')');
return oom;
} // end of MakeInsert
/***********************************************************************/
@@ -591,7 +626,7 @@ bool TDBODBC::BindParameters(PGLOBAL g)
/* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */
/***********************************************************************/
char *TDBODBC::MakeCommand(PGLOBAL g)
bool TDBODBC::MakeCommand(PGLOBAL g)
{
char *p, *stmt, name[68], *body = NULL, *qc = Ocp->GetQuoteChar();
char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
@@ -649,7 +684,8 @@ char *TDBODBC::MakeCommand(PGLOBAL g)
return NULL;
} // endif p
return stmt;
Query = new(g) STRING(g, 0, stmt);
return (!Query->GetSize());
} // end of MakeCommand
#if 0
@@ -826,10 +862,12 @@ bool TDBODBC::OpenDB(PGLOBAL g)
if (Memory < 3) {
// Method will depend on cursor type
if ((Rbuf = Ocp->Rewind(Query, (PODBCCOL)Columns)) < 0) {
Ocp->Close();
return true;
} // endif Rewind
if ((Rbuf = Ocp->Rewind(Query->GetStr(), (PODBCCOL)Columns)) < 0)
if (Mode != MODE_READX) {
Ocp->Close();
return true;
} else
Rbuf = 0;
} else
Rbuf = Qrp->Nblin;
@@ -864,15 +902,14 @@ bool TDBODBC::OpenDB(PGLOBAL g)
/*********************************************************************/
if (Mode == MODE_READ || Mode == MODE_READX) {
if (Memory > 1 && !Srcdef) {
char *Sql;
int n;
int n;
if ((Sql = MakeSQL(g, true))) {
if (!MakeSQL(g, true)) {
// Allocate a Count(*) column
Cnp = new(g) ODBCCOL;
Cnp->InitValue(g);
if ((n = Ocp->GetResultSize(Sql, Cnp)) < 0) {
if ((n = Ocp->GetResultSize(Query->GetStr(), Cnp)) < 0) {
strcpy(g->Message, "Cannot get result size");
return true;
} // endif n
@@ -882,36 +919,36 @@ bool TDBODBC::OpenDB(PGLOBAL g)
if ((Qrp = Ocp->AllocateResult(g)))
Memory = 2; // Must be filled
else {
strcpy(g->Message, "Memory allocation failed");
strcpy(g->Message, "Result set memory allocation failed");
return true;
} // endif n
Ocp->m_Rows = 0;
} else {
strcpy(g->Message, "MakeSQL failed");
} else
return true;
} // endif Sql
} // endif Memory
if ((Query = MakeSQL(g, false))) {
if (!(rc = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
colp = (PODBCCOL)colp->GetNext())
if (!colp->IsSpecial())
colp->AllocateBuffers(g, Rows);
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0);
} // endif Query
rc = (Mode == MODE_READ)
? ((Rows = Ocp->ExecDirectSQL(Query->GetStr(), (PODBCCOL)Columns)) < 0)
: false;
} // endif rc
} else if (Mode == MODE_INSERT) {
if ((Query = MakeInsert(g))) {
if (Nparm != Ocp->PrepareSQL(Query)) {
if (!(rc = MakeInsert(g))) {
if (Nparm != Ocp->PrepareSQL(Query->GetStr())) {
strcpy(g->Message, MSG(PARM_CNT_MISS));
rc = true;
} else
rc = BindParameters(g);
} // endif Query
} // endif rc
} else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
rc = false; // wait for CheckCond before calling MakeCommand(g);
@@ -969,6 +1006,59 @@ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos)
return false;
} // end of SetRecpos
/***********************************************************************/
/* Data Base indexed read routine for MYSQL access method. */
/***********************************************************************/
bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
{
char c = Quote ? *Quote : 0;
int oldlen = Query->GetLength();
PHC hc = To_Def->GetHandler();
if (!(kr || hc->end_range) || op == OP_NEXT ||
Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!kr && Mode == MODE_READX) {
// This is a false indexed read
Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns);
Mode = MODE_READ;
return (Rows < 0);
} // endif key
return false;
} else {
if (To_Def->GetHandler()->MakeKeyWhere(g, Query, op, c, kr))
return true;
if (To_CondFil) {
if (To_CondFil->Idx != hc->active_index) {
To_CondFil->Idx = hc->active_index;
To_CondFil->Body= (char*)PlugSubAlloc(g, NULL, 0);
*To_CondFil->Body= 0;
if ((To_CondFil = hc->CheckCond(g, To_CondFil, To_CondFil->Cond)))
PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
} // endif active_index
if (To_CondFil)
if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) {
strcpy(g->Message, "Readkey: Out of memory");
return true;
} // endif Append
} // endif To_Condfil
Mode = MODE_READ;
} // endif's op
if (trace)
htrc("ODBC ReadKey: Query=%s\n", Query->GetStr());
Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns);
Query->Truncate(oldlen);
return (Rows < 0);
} // end of ReadKey
/***********************************************************************/
/* VRDNDOS: Data Base read routine for odbc access method. */
/***********************************************************************/
@@ -981,11 +1071,11 @@ int TDBODBC::ReadDB(PGLOBAL g)
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!Query && !(Query = MakeCommand(g)))
if (!Query && MakeCommand(g))
return RC_FX;
// Send the UPDATE/DELETE command to the remote table
if (!Ocp->ExecSQLcommand(Query)) {
if (!Ocp->ExecSQLcommand(Query->GetStr())) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
if (trace)
@@ -1063,11 +1153,11 @@ int TDBODBC::WriteDB(PGLOBAL g)
int TDBODBC::DeleteDB(PGLOBAL g, int irc)
{
if (irc == RC_FX) {
if (!Query && !(Query = MakeCommand(g)))
if (!Query && MakeCommand(g))
return RC_FX;
// Send the DELETE (all) command to the remote table
if (!Ocp->ExecSQLcommand(Query)) {
if (!Ocp->ExecSQLcommand(Query->GetStr())) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
if (trace)
@@ -1279,12 +1369,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
} // endif Buf_Type
// Nulls are handled by StrLen[n] == SQL_NULL_DATA
// MDEV-8561
//if (Value->IsZero())
// Value->SetNull(Nullable);
if (trace) {
if (trace > 1) {
char buf[64];
htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n",
@@ -1572,9 +1657,12 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
int TDBXDBC::ReadDB(PGLOBAL g)
{
if (Cmdlist) {
Query = Cmdlist->Cmd;
if (!Query)
Query = new(g)STRING(g, 0, Cmdlist->Cmd);
else
Query->Set(Cmdlist->Cmd);
if (Ocp->ExecSQLcommand(Query))
if (Ocp->ExecSQLcommand(Query->GetStr()))
Nerr++;
Fpos++; // Used for progress info
@@ -1632,10 +1720,10 @@ void XSRCCOL::ReadColumn(PGLOBAL g)
PTDBXDBC tdbp = (PTDBXDBC)To_Tdb;
switch (Flag) {
case 0: Value->SetValue_psz(tdbp->Query); break;
case 1: Value->SetValue(tdbp->AftRows); break;
case 2: Value->SetValue_psz(g->Message); break;
default: Value->SetValue_psz("Invalid Flag"); break;
case 0: Value->SetValue_psz(tdbp->Query->GetStr()); break;
case 1: Value->SetValue(tdbp->AftRows); break;
case 2: Value->SetValue_psz(g->Message); break;
default: Value->SetValue_psz("Invalid Flag"); break;
} // endswitch Flag
} // end of ReadColumn

View File

@@ -42,7 +42,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
int GetOptions(void) {return Options;}
// Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual int Indexable(void) {return 2;}
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
protected:
@@ -111,15 +112,14 @@ class TDBODBC : public TDBASE {
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{return true;}
virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr);
protected:
// Internal functions
int Decode(char *utf, char *buf, size_t n);
char *MakeSQL(PGLOBAL g, bool cnt);
char *MakeInsert(PGLOBAL g);
char *MakeCommand(PGLOBAL g);
bool MakeSQL(PGLOBAL g, bool cnt);
bool MakeInsert(PGLOBAL g);
bool MakeCommand(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g);
//char *MakeUpdate(PGLOBAL g);
@@ -129,14 +129,14 @@ class TDBODBC : public TDBASE {
ODBConn *Ocp; // Points to an ODBC connection class
ODBCCOL *Cnp; // Points to count(*) column
ODBCPARM Ops; // Additional parameters
char *Connect; // Points to connection string
PSTRG Query; // Constructed SQL query
char *Connect; // Points to connection string
char *TableName; // Points to ODBC table name
char *Schema; // Points to ODBC table Schema
char *User; // User connect info
char *Pwd; // Password connect info
char *Catalog; // Points to ODBC table Catalog
char *Srcdef; // The source table SQL definition
char *Query; // Points to SQL statement
char *Count; // Points to count(*) SQL statement
//char *Where; // Points to local where clause
char *Quote; // The identifier quoting character

View File

@@ -60,7 +60,7 @@ extern "C" char version[];
#endif // !__WIN__
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
#define XSTR(M) sizeof(M) - strlen(M) - 1 /* To avoid overflow*/
#define XLEN(M) sizeof(M) - strlen(M) - 1 /* To avoid overflow*/
/***********************************************************************/
/* Class and structure used by XMLColumns. */
@@ -226,30 +226,30 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
more:
if (vp->atp) {
strncpy(colname, vp->atp->GetName(g), sizeof(colname));
strncat(xcol->Name, colname, XSTR(xcol->Name));
strncat(xcol->Name, colname, XLEN(xcol->Name));
switch (vp->atp->GetText(g, buf, sizeof(buf))) {
case RC_INFO:
PushWarning(g, txmp);
case RC_OK:
strncat(fmt, "@", XSTR(fmt));
strncat(fmt, "@", XLEN(fmt));
break;
default:
goto err;
} // enswitch rc
if (j)
strncat(fmt, colname, XSTR(fmt));
strncat(fmt, colname, XLEN(fmt));
} else {
if (tdp->Usedom && node->GetType() != 1)
continue;
strncpy(colname, node->GetName(g), sizeof(colname));
strncat(xcol->Name, colname, XSTR(xcol->Name));
strncat(xcol->Name, colname, XLEN(xcol->Name));
if (j)
strncat(fmt, colname, XSTR(fmt));
strncat(fmt, colname, XLEN(fmt));
if (j < lvl && ok) {
vp = lvlp[j+1];
@@ -267,10 +267,10 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
if (!vp->atp)
node = vp->nl->GetItem(g, vp->k++, node);
strncat(fmt, colname, XSTR(fmt));
strncat(fmt, "/", XSTR(fmt));
strncat(xcol->Name, "_", XSTR(xcol->Name));
j++;
strncat(fmt, colname, XLEN(fmt));
strncat(fmt, "/", XLEN(fmt));
strncat(xcol->Name, "_", XLEN(xcol->Name));
j++;
vp->n = (int)strlen(xcol->Name);
vp->m = (int)strlen(fmt);
goto more;

View File

@@ -340,7 +340,7 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type, short prec)
switch (type) {
case TYPE_STRING:
valp = new(g) TYPVAL<PSZ>((PSZ)value);
valp = new(g) TYPVAL<PSZ>((PSZ)value, prec);
break;
case TYPE_SHORT:
valp = new(g) TYPVAL<short>(*(short*)value, TYPE_SHORT);
@@ -1209,12 +1209,12 @@ void TYPVAL<TYPE>::Print(PGLOBAL g, char *ps, uint z)
/***********************************************************************/
/* STRING public constructor from a constant string. */
/***********************************************************************/
TYPVAL<PSZ>::TYPVAL(PSZ s) : VALUE(TYPE_STRING)
TYPVAL<PSZ>::TYPVAL(PSZ s, short c) : VALUE(TYPE_STRING)
{
Strp = s;
Len = strlen(s);
Clen = Len;
Ci = false;
Ci = (c == 1);
} // end of STRING constructor
/***********************************************************************/

View File

@@ -216,7 +216,7 @@ template <>
class DllExport TYPVAL<PSZ>: public VALUE {
public:
// Constructors
TYPVAL(PSZ s);
TYPVAL(PSZ s, short c = 0);
TYPVAL(PGLOBAL g, PSZ s, int n, int c);
// Implementation

View File

@@ -11,6 +11,7 @@
/* Include mariaDB header file. */
/***********************************************************************/
#include "my_global.h"
#include "m_string.h"
/***********************************************************************/
/* Include required application header files */
@@ -290,14 +291,14 @@ bool STRING::Set(char *s, uint n)
} // end of Set
/***********************************************************************/
/* Append a char* to a STRING. */
/* Append a char* to a STRING. */
/***********************************************************************/
bool STRING::Append(const char *s, uint ln)
bool STRING::Append(const char *s, uint ln, bool nq)
{
if (!s)
return false;
uint len = Length + ln + 1;
uint i, len = Length + ln + 1;
if (len > Size) {
char *p = Realloc(len);
@@ -311,8 +312,22 @@ bool STRING::Append(const char *s, uint ln)
} // endif n
strncpy(Strp + Length, s, ln);
Length = len - 1;
if (nq) {
for (i = 0; i < ln; i++)
switch (s[i]) {
case '\\': Strp[Length++] = '\\'; Strp[Length++] = '\\'; break;
case '\0': Strp[Length++] = '\\'; Strp[Length++] = '0'; break;
case '\'': Strp[Length++] = '\\'; Strp[Length++] = '\''; break;
case '\n': Strp[Length++] = '\\'; Strp[Length++] = 'n'; break;
case '\r': Strp[Length++] = '\\'; Strp[Length++] = 'r'; break;
case '\032': Strp[Length++] = '\\'; Strp[Length++] = 'Z'; break;
default: Strp[Length++] = s[i];
} // endswitch s[i]
} else
for (i = 0; i < ln && s[i]; i++)
Strp[Length++] = s[i];
Strp[Length] = 0;
return false;
} // end of Append

View File

@@ -134,7 +134,7 @@ class DllExport STRING : public BLOCK {
inline void Reset(void) {*Strp = 0;}
bool Set(PSZ s);
bool Set(char *s, uint n);
bool Append(const char *s, uint ln);
bool Append(const char *s, uint ln, bool nq = false);
bool Append(PSZ s);
bool Append(STRING &str);
bool Append(char c);

View File

@@ -19,6 +19,7 @@
#include "m_ctype.h"
typedef class CMD *PCMD;
typedef struct st_key_range key_range;
// Commands executed by XDBC and MYX tables
class CMD : public BLOCK {
@@ -32,12 +33,24 @@ class CMD : public BLOCK {
}; // end of class CMD
// Condition filter structure
typedef struct _cond_filter {
char *Body;
OPVAL Op;
PCMD Cmds;
} CONDFIL, *PCFIL;
class CONDFIL : public BLOCK {
public:
// Constructor
CONDFIL(const Item *cond, uint idx, AMT type)
{
Cond = cond; Idx = idx; Type = type; Body = NULL; Op = OP_XX; Cmds = NULL;
}
// Members
const Item *Cond;
AMT Type;
uint Idx;
char *Body;
OPVAL Op;
PCMD Cmds;
}; // end of class CONDFIL
typedef class CONDFIL *PCFIL;
typedef class TDBCAT *PTDBCAT;
typedef class CATCOL *PCATCOL;
@@ -109,7 +122,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
virtual int DeleteDB(PGLOBAL, int) = 0;
virtual void CloseDB(PGLOBAL) = 0;
virtual int CheckWrite(PGLOBAL) {return 0;}
virtual bool ReadKey(PGLOBAL, OPVAL, const void *, int) = 0;
virtual bool ReadKey(PGLOBAL, OPVAL, const key_range *) = 0;
protected:
// Members
@@ -188,7 +201,7 @@ class DllExport TDBASE : public TDB {
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
virtual int MakeIndex(PGLOBAL g, PIXDEF, bool)
{strcpy(g->Message, "Remote index"); return RC_INFO;}
virtual bool ReadKey(PGLOBAL, OPVAL, const void *, int)
virtual bool ReadKey(PGLOBAL, OPVAL, const key_range *)
{assert(false); return true;}
protected: