summaryrefslogtreecommitdiff
path: root/storage/connect
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2014-02-27 18:00:01 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2014-02-27 18:00:01 +0100
commit43362bc9a005edff28b0470789cd8d9571b022cb (patch)
treea3f7a12489a41c7d5a8a4b0809d74764966da72b /storage/connect
parent1699947eef6a73d69ec759b882bebae8bf94fa16 (diff)
downloadmariadb-git-43362bc9a005edff28b0470789cd8d9571b022cb.tar.gz
- Fix bug MDEV-5734
modified: storage/connect/mysql-test/connect/r/pivot.result storage/connect/mysql-test/connect/t/pivot.test storage/connect/tabmysql.cpp storage/connect/tabpivot.cpp - Implement a first experimental support of MRR (compiled only if MRRBKA_SUPPORT is defined) modified: storage/connect/colblk.h storage/connect/connect.cc storage/connect/connect.h storage/connect/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/plugutil.c storage/connect/user_connect.cc
Diffstat (limited to 'storage/connect')
-rw-r--r--storage/connect/colblk.h3
-rw-r--r--storage/connect/connect.cc47
-rw-r--r--storage/connect/connect.h5
-rw-r--r--storage/connect/global.h3
-rw-r--r--storage/connect/ha_connect.cc45
-rw-r--r--storage/connect/ha_connect.h9
-rw-r--r--storage/connect/mysql-test/connect/r/pivot.result27
-rw-r--r--storage/connect/mysql-test/connect/t/pivot.test309
-rw-r--r--storage/connect/plugutil.c3
-rw-r--r--storage/connect/tabmysql.cpp3
-rw-r--r--storage/connect/tabpivot.cpp4
-rw-r--r--storage/connect/user_connect.cc3
12 files changed, 283 insertions, 178 deletions
diff --git a/storage/connect/colblk.h b/storage/connect/colblk.h
index 11fca3e4fb7..7b84d237bd2 100644
--- a/storage/connect/colblk.h
+++ b/storage/connect/colblk.h
@@ -49,6 +49,9 @@ class DllExport COLBLK : public XOBJECT {
void AddColUse(ushort u) {ColUse |= u;}
void AddStatus(ushort u) {Status |= u;}
void SetNext(PCOL cp) {Next = cp;}
+#if defined(MRRBKA_SUPPORT)
+ PXCOL GetKcol(void) {return To_Kcol;}
+#endif // MRRBKA_SUPPORT
void SetKcol(PXCOL kcp) {To_Kcol = kcp;}
PCOLDEF GetCdp(void) {return Cdp;}
PSZ GetDomain(void) {return (Cdp) ? Cdp->Decode : NULL;}
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 9340ae97258..d111ff07044 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -57,7 +57,7 @@ extern int xtrace;
/* Routines called internally by semantic routines. */
/***********************************************************************/
void CntEndDB(PGLOBAL);
-RCODE EvalColumns(PGLOBAL g, PTDB tdbp);
+RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool mrr= false);
/***********************************************************************/
/* MySQL routines called externally by semantic routines. */
@@ -187,7 +187,7 @@ bool CntInfo(PGLOBAL g, PTDB tp, PXF info)
/***********************************************************************/
PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
{
- int rc;
+ int rc;
PTDB tdbp;
PTABLE tabp;
PDBUSER dup= PlgGetUser(g);
@@ -237,7 +237,8 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
bool del, PHC h)
{
char *p;
- int i, n;
+ int i, n, rc;
+ bool rcop= true;
PCOL colp;
//PCOLUMN cp;
PDBUSER dup= PlgGetUser(g);
@@ -251,7 +252,15 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
return true;
} // endif tdbp
-//tdbp->SetMode(mode); done in ha_connect::GetTDB
+ // Save stack and allocation environment and prepare error return
+ if (g->jump_level == MAX_JUMP) {
+ strcpy(g->Message, MSG(TOO_MANY_JUMPS));
+ return true;
+ } // endif jump_level
+
+ if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
+ goto err;
+ } // endif rc
if (!c1) {
if (mode == MODE_INSERT)
@@ -273,7 +282,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (!colp) {
sprintf(g->Message, "Column %s not found in %s", p, tdbp->GetName());
- return true;
+ goto err;
} // endif colp
n= strlen(p) + 1;
@@ -281,12 +290,12 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
for (i= 0, colp= tdbp->GetColumns(); colp; i++, colp= colp->GetNext()) {
if (colp->InitValue(g))
- return true;
+ goto err;
if (mode == MODE_INSERT)
// Allow type conversion
if (colp->SetBuffer(g, colp->GetValue(), true, false))
- return true;
+ goto err;
colp->AddColUse(U_P); // For PLG tables
} // endfor colp
@@ -301,7 +310,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (!(utp= (PTDBASE)tdbp->Duplicate(g))) {
sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName());
- return true;
+ goto err;
} // endif tp
if (!c2)
@@ -315,10 +324,10 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
for (i= 0, colp= utp->GetColumns(); colp; i++, colp= colp->GetNext()) {
if (colp->InitValue(g))
- return true;
+ goto err;
if (colp->SetBuffer(g, colp->GetValue(), true, false))
- return true;
+ goto err;
} // endfor colp
@@ -350,13 +359,17 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (mode != MODE_ANY && mode != MODE_ALTER) {
if (tdbp->OpenDB(g)) {
printf("%s\n", g->Message);
- return true;
+ goto err;
} else
tdbp->SetNext(NULL);
} // endif mode
- return false;
+ rcop= false;
+
+ err:
+ g->jump_level--;
+ return rcop;
} // end of CntOpenTable
/***********************************************************************/
@@ -374,7 +387,7 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp)
/***********************************************************************/
/* Evaluate all columns after a record is read. */
/***********************************************************************/
-RCODE EvalColumns(PGLOBAL g, PTDB tdbp)
+RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool mrr)
{
RCODE rc= RC_OK;
PCOL colp;
@@ -402,7 +415,11 @@ RCODE EvalColumns(PGLOBAL g, PTDB tdbp)
colp->Reset();
// Virtual columns are computed by MariaDB
+#if defined(MRRBKA_SUPPORT)
+ if (!colp->GetColUse(U_VIRTUAL) && (!mrr || colp->GetKcol()))
+#else // !MRRBKA_SUPPORT
if (!colp->GetColUse(U_VIRTUAL))
+#endif // !MRRBKA_SUPPORT
if (colp->Eval(g))
rc= RC_FX;
@@ -680,7 +697,7 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id)
/* IndexRead: fetch a record having the index value. */
/***********************************************************************/
RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
- const void *key, int len)
+ const void *key, int len, bool mrr)
{
char *kp= (char*)key;
int n;
@@ -757,7 +774,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
xbp->SetNth(0);
if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK)
- rc= EvalColumns(g, tdbp);
+ rc= EvalColumns(g, tdbp, mrr);
return rc;
} // end of CntIndexRead
diff --git a/storage/connect/connect.h b/storage/connect/connect.h
index 4b3e2fb7347..bf97d61b35f 100644
--- a/storage/connect/connect.h
+++ b/storage/connect/connect.h
@@ -37,7 +37,8 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp);
int CntCloseTable(PGLOBAL g, PTDB tdbp);
int CntIndexInit(PGLOBAL g, PTDB tdbp, int id);
RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
-RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n);
+RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n,
+ bool mrr = false);
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp);
RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp);
RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all);
@@ -63,7 +64,7 @@ class TDBDOX: public TDBDOS {
friend int MakeIndex(PGLOBAL, PTDB, PIXDEF);
friend int CntCloseTable(PGLOBAL, PTDB);
friend int CntIndexInit(PGLOBAL, PTDB, int);
- friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const void*, int);
+ friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const void*, int, bool);
friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool);
friend int CntIndexRange(PGLOBAL, PTDB, const uchar**, uint*,
bool*, key_part_map*);
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 8bccd742a64..374ba6e4177 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -222,6 +222,9 @@ typedef struct _global { /* Global structure */
int Createas; /* To pass info to created table */
void *Xchk; /* indexes in create/alter */
short Alchecked; /* Checked for ALTER */
+#if defined(MRRBKA_SUPPORT)
+ short Mrr; /* True when doing mrr */
+#endif // MRRBKA_SUPPORT
short Trace;
int jump_level;
jmp_buf jumper[MAX_JUMP + 2];
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 7fd652e5bc2..f19cac9da50 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -481,6 +481,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
creat_query_id= (table && table->in_use) ? table->in_use->query_id : 0;
stop= false;
alter= false;
+ mrr= false;
indexing= -1;
locked= 0;
data_file_name= NULL;
@@ -1357,10 +1358,20 @@ int ha_connect::MakeRecord(char *buf)
if (bitmap_is_set(map, fp->field_index) || alter) {
// This is a used field, fill the buffer with value
for (colp= tdbp->GetColumns(); colp; colp= colp->GetNext())
+#if defined(MRRBKA_SUPPORT)
+ if ((!mrr || colp->GetKcol()) &&
+ !stricmp(colp->GetName(), (char*)fp->field_name))
+ break;
+#else // !MRRBKA_SUPPORT
if (!stricmp(colp->GetName(), (char*)fp->field_name))
break;
+#endif // !MRRBKA_SUPPORT
if (!colp) {
+#if defined(MRRBKA_SUPPORT)
+ if (mrr)
+ continue;
+#endif // MRRBKA_SUPPORT
printf("Column %s not found\n", fp->field_name);
dbug_tmp_restore_column_map(table->write_set, org_bitmap);
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
@@ -2020,9 +2031,17 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
PGLOBAL g= (xp) ? xp->g : NULL;
// Try to set the database environment
- if (g)
+ if (g) {
rc= (CntCheckDB(g, this, name)) ? (-2) : 0;
- else
+#if defined(MRRBKA_SUPPORT)
+ if (g->Mrr) {
+ // This should only happen for the mrr secondary handler
+ mrr= true;
+ g->Mrr= false;
+ } else
+ mrr= false;
+#endif // MRRBKA_SUPPORT
+ } else
rc= HA_ERR_INTERNAL_ERROR;
DBUG_RETURN(rc);
@@ -2317,7 +2336,7 @@ int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const uchar *key, uint key_len
//statistic_increment(ha_read_key_count, &LOCK_status);
- switch (CntIndexRead(xp->g, tdbp, op, key, (int)key_len)) {
+ switch (CntIndexRead(xp->g, tdbp, op, key, (int)key_len, mrr)) {
case RC_OK:
xp->fnd++;
rc= MakeRecord((char*)buf);
@@ -5401,7 +5420,7 @@ bool ha_connect::check_if_incompatible_data(HA_CREATE_INFO *info,
#if defined(MRRBKA_SUPPORT)
-#error This is not implemented yet
+//#error This is not implemented yet
/****************************************************************************
* CONNECT MRR implementation: use DS-MRR
This is just copied from myisam
@@ -5433,10 +5452,12 @@ ha_rows ha_connect::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
// MMR is implemented for "local" file based tables only
if (!IsFileType(GetRealType(GetTableOptionStruct(table))))
- *flags |= HA_MRR_USE_DEFAULT_IMPL;
+ *flags|= HA_MRR_USE_DEFAULT_IMPL;
- return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
- flags, cost);
+ ha_rows rows= ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges,
+ bufsz, flags, cost);
+ xp->g->Mrr= !(*flags & HA_MRR_USE_DEFAULT_IMPL);
+ return rows;
} // end of multi_range_read_info_const
ha_rows ha_connect::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
@@ -5444,7 +5465,15 @@ ha_rows ha_connect::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
uint *flags, Cost_estimate *cost)
{
ds_mrr.init(this, table);
- return ds_mrr.dsmrr_info(keyno, n_ranges, keys, key_parts, bufsz, flags, cost);
+
+ // MMR is implemented for "local" file based tables only
+ if (!IsFileType(GetRealType(GetTableOptionStruct(table))))
+ *flags|= HA_MRR_USE_DEFAULT_IMPL;
+
+ ha_rows rows= ds_mrr.dsmrr_info(keyno, n_ranges, keys, key_parts, bufsz,
+ flags, cost);
+ xp->g->Mrr= !(*flags & HA_MRR_USE_DEFAULT_IMPL);
+ return rows;
} // end of multi_range_read_info
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 7983ec72bdc..1bd3991e907 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -243,8 +243,12 @@ public:
*/
ulong index_flags(uint inx, uint part, bool all_parts) const
{
- return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER;
- }
+ return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER
+#if defined(MRRBKA_SUPPORT)
+ | HA_KEYREAD_ONLY
+#endif // MRRBKA_SUPPORT
+ ;
+ } // end of index_flags
/** @brief
unireg.cc will call max_supported_record_length(), max_supported_keys(),
@@ -484,6 +488,7 @@ protected:
bool valid_info; // True if xinfo is valid
bool stop; // Used when creating index
bool alter; // True when converting to other engine
+ bool mrr; // True when getting index positions
int indexing; // Type of indexing for CONNECT
int locked; // Table lock
THR_LOCK_DATA lock_data;
diff --git a/storage/connect/mysql-test/connect/r/pivot.result b/storage/connect/mysql-test/connect/r/pivot.result
index 2e4a924c8c3..82b1e0a0b0b 100644
--- a/storage/connect/mysql-test/connect/r/pivot.result
+++ b/storage/connect/mysql-test/connect/r/pivot.result
@@ -224,3 +224,30 @@ Kevin 0 2 6
Donald 1 0 3
DROP TABLE pivet;
DROP TABLE pets;
+#
+# MDEV-5734
+#
+CREATE TABLE fruit (
+`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+`name` varchar(32) DEFAULT NULL,
+`cnt` int(11) DEFAULT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
+INSERT INTO fruit VALUES (1,'apple',1),(2,'banana',1),(3,'apple',2),(4,'cherry',4),(5,'durazno',2);
+SELECT * FROM fruit;
+id name cnt
+1 apple 1
+2 banana 1
+3 apple 2
+4 cherry 4
+5 durazno 2
+CREATE TABLE fruit_pivot ENGINE=CONNECT TABLE_TYPE=pivot TABNAME=fruit;
+SELECT * FROM fruit_pivot;
+id apple banana cherry durazno
+1 1 0 0 0
+2 0 1 0 0
+3 2 0 0 0
+4 0 0 4 0
+5 0 0 0 2
+DROP TABLE fruit_pivot;
+DROP TABLE fruit;
diff --git a/storage/connect/mysql-test/connect/t/pivot.test b/storage/connect/mysql-test/connect/t/pivot.test
index 7679434bca8..3212496a220 100644
--- a/storage/connect/mysql-test/connect/t/pivot.test
+++ b/storage/connect/mysql-test/connect/t/pivot.test
@@ -1,146 +1,163 @@
--- source include/not_embedded.inc
-
-let $MYSQLD_DATADIR= `select @@datadir`;
-let $PORT= `select @@port`;
---copy_file $MTR_SUITE_DIR/std_data/expenses.txt $MYSQLD_DATADIR/test/expenses.txt
-
---echo #
---echo # Testing the PIVOT table type
---echo #
-CREATE TABLE expenses (
-Who CHAR(10) NOT NULL,
-Week INT(2) NOT NULL,
-What CHAR(12) NOT NULL,
-Amount DOUBLE(8,2))
-ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='expenses.txt' ENDING=2;
-SELECT * FROM expenses;
-
---echo #
---echo # Pivoting from What
---echo #
-CREATE TABLE pivex (
-Who CHAR(10) NOT NULL,
-Week INT(2) NOT NULL,
-Beer DOUBLE(8,2) FLAG=1,
-Car DOUBLE(8,2) FLAG=1,
-Food DOUBLE(8,2) FLAG=1)
-ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
---replace_result $PORT PORT
---eval ALTER TABLE pivex OPTION_LIST='port=$PORT'
-SELECT * FROM pivex;
-
---echo #
---echo # Restricting the columns in a Pivot Table
---echo #
-ALTER TABLE pivex DROP COLUMN week;
-SELECT * FROM pivex;
-
---echo #
---echo # Using a source definition
---echo #
-DROP TABLE pivex;
-CREATE TABLE pivex (
-Who CHAR(10) NOT NULL,
-Week INT(2) NOT NULL,
-Beer DOUBLE(8,2) FLAG=1,
-Car DOUBLE(8,2) FLAG=1,
-Food DOUBLE(8,2) FLAG=1)
-ENGINE=CONNECT TABLE_TYPE=PIVOT
-SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what';
---replace_result $PORT PORT
---eval ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=$PORT'
-SELECT * FROM pivex;
-
---echo #
---echo # Pivoting from Week
---echo #
-DROP TABLE pivex;
-CREATE TABLE pivex (
-Who CHAR(10) NOT NULL,
-What CHAR(12) NOT NULL,
-`3` DOUBLE(8,2) FLAG=1,
-`4` DOUBLE(8,2) FLAG=1,
-`5` DOUBLE(8,2) FLAG=1)
-ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
---replace_result $PORT PORT
---eval ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=$PORT'
-SELECT * FROM pivex;
-
---echo #
---echo # Using scalar functions and expresssions
---echo #
-DROP TABLE pivex;
-CREATE TABLE pivex (
-Who CHAR(10) NOT NULL,
-What CHAR(12) NOT NULL,
-First DOUBLE(8,2) FLAG=1,
-Middle DOUBLE(8,2) FLAG=1,
-Last DOUBLE(8,2) FLAG=1)
-ENGINE=CONNECT TABLE_TYPE=PIVOT
-SRCDEF='select who, what, case when week=3 then ''First'' when week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) * 6.56 as amnt from expenses group by who, what, wk';
---replace_result $PORT PORT
---eval ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=$PORT'
-SELECT * FROM pivex;
-DROP TABLE pivex;
-DROP TABLE expenses;
-
---echo #
---echo # Make the PETS table
---echo #
-CREATE TABLE pets (
-Name VARCHAR(12) NOT NULL,
-Race CHAR(6) NOT NULL,
-Number INT NOT NULL) ENGINE=MYISAM;
-INSERT INTO pets VALUES('John','dog',2);
-INSERT INTO pets VALUES('Bill','cat',1);
-INSERT INTO pets VALUES('Mary','dog',1);
-INSERT INTO pets VALUES('Mary','cat',1);
-INSERT INTO pets VALUES('Lisbeth','rabbit',2);
-INSERT INTO pets VALUES('Kevin','cat',2);
-INSERT INTO pets VALUES('Kevin','bird',6);
-INSERT INTO pets VALUES('Donald','dog',1);
-INSERT INTO pets VALUES('Donald','fish',3);
-SELECT * FROM pets;
-
---echo #
---echo # Pivot the PETS table
---echo #
-CREATE TABLE pivet (
-name VARCHAR(12) NOT NULL,
-dog INT NOT NULL DEFAULT 0 FLAG=1,
-cat INT NOT NULL DEFAULT 0 FLAG=1,
-rabbit INT NOT NULL DEFAULT 0 FLAG=1,
-bird INT NOT NULL DEFAULT 0 FLAG=1,
-fish INT NOT NULL DEFAULT 0 FLAG=1)
-ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
-SELECT * FROM pivet;
-DROP TABLE pivet;
-
---echo #
---echo # Testing the "data" column list
---echo #
-CREATE TABLE pivet (
-name VARCHAR(12) NOT NULL,
-dog INT NOT NULL DEFAULT 0 FLAG=1,
-cat INT NOT NULL DEFAULT 0 FLAG=1)
-ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
---error ER_GET_ERRMSG
-SELECT * FROM pivet;
-ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1';
-SELECT * FROM pivet;
-DROP TABLE pivet;
-
---echo #
---echo # Adding a "dump" column
---echo #
-CREATE TABLE pivet (
-name VARCHAR(12) NOT NULL,
-dog INT NOT NULL DEFAULT 0 FLAG=1,
-cat INT NOT NULL DEFAULT 0 FLAG=1,
-other INT NOT NULL DEFAULT 0 FLAG=2)
-ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
-SELECT * FROM pivet;
-
-DROP TABLE pivet;
-DROP TABLE pets;
---remove_file $MYSQLD_DATADIR/test/expenses.txt
+-- source include/not_embedded.inc
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+let $PORT= `select @@port`;
+--copy_file $MTR_SUITE_DIR/std_data/expenses.txt $MYSQLD_DATADIR/test/expenses.txt
+
+--echo #
+--echo # Testing the PIVOT table type
+--echo #
+CREATE TABLE expenses (
+Who CHAR(10) NOT NULL,
+Week INT(2) NOT NULL,
+What CHAR(12) NOT NULL,
+Amount DOUBLE(8,2))
+ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='expenses.txt' ENDING=2;
+SELECT * FROM expenses;
+
+--echo #
+--echo # Pivoting from What
+--echo #
+CREATE TABLE pivex (
+Who CHAR(10) NOT NULL,
+Week INT(2) NOT NULL,
+Beer DOUBLE(8,2) FLAG=1,
+Car DOUBLE(8,2) FLAG=1,
+Food DOUBLE(8,2) FLAG=1)
+ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
+--replace_result $PORT PORT
+--eval ALTER TABLE pivex OPTION_LIST='port=$PORT'
+SELECT * FROM pivex;
+
+--echo #
+--echo # Restricting the columns in a Pivot Table
+--echo #
+ALTER TABLE pivex DROP COLUMN week;
+SELECT * FROM pivex;
+
+--echo #
+--echo # Using a source definition
+--echo #
+DROP TABLE pivex;
+CREATE TABLE pivex (
+Who CHAR(10) NOT NULL,
+Week INT(2) NOT NULL,
+Beer DOUBLE(8,2) FLAG=1,
+Car DOUBLE(8,2) FLAG=1,
+Food DOUBLE(8,2) FLAG=1)
+ENGINE=CONNECT TABLE_TYPE=PIVOT
+SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what';
+--replace_result $PORT PORT
+--eval ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=$PORT'
+SELECT * FROM pivex;
+
+--echo #
+--echo # Pivoting from Week
+--echo #
+DROP TABLE pivex;
+CREATE TABLE pivex (
+Who CHAR(10) NOT NULL,
+What CHAR(12) NOT NULL,
+`3` DOUBLE(8,2) FLAG=1,
+`4` DOUBLE(8,2) FLAG=1,
+`5` DOUBLE(8,2) FLAG=1)
+ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
+--replace_result $PORT PORT
+--eval ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=$PORT'
+SELECT * FROM pivex;
+
+--echo #
+--echo # Using scalar functions and expresssions
+--echo #
+DROP TABLE pivex;
+CREATE TABLE pivex (
+Who CHAR(10) NOT NULL,
+What CHAR(12) NOT NULL,
+First DOUBLE(8,2) FLAG=1,
+Middle DOUBLE(8,2) FLAG=1,
+Last DOUBLE(8,2) FLAG=1)
+ENGINE=CONNECT TABLE_TYPE=PIVOT
+SRCDEF='select who, what, case when week=3 then ''First'' when week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) * 6.56 as amnt from expenses group by who, what, wk';
+--replace_result $PORT PORT
+--eval ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=$PORT'
+SELECT * FROM pivex;
+DROP TABLE pivex;
+DROP TABLE expenses;
+
+--echo #
+--echo # Make the PETS table
+--echo #
+CREATE TABLE pets (
+Name VARCHAR(12) NOT NULL,
+Race CHAR(6) NOT NULL,
+Number INT NOT NULL) ENGINE=MYISAM;
+INSERT INTO pets VALUES('John','dog',2);
+INSERT INTO pets VALUES('Bill','cat',1);
+INSERT INTO pets VALUES('Mary','dog',1);
+INSERT INTO pets VALUES('Mary','cat',1);
+INSERT INTO pets VALUES('Lisbeth','rabbit',2);
+INSERT INTO pets VALUES('Kevin','cat',2);
+INSERT INTO pets VALUES('Kevin','bird',6);
+INSERT INTO pets VALUES('Donald','dog',1);
+INSERT INTO pets VALUES('Donald','fish',3);
+SELECT * FROM pets;
+
+--echo #
+--echo # Pivot the PETS table
+--echo #
+CREATE TABLE pivet (
+name VARCHAR(12) NOT NULL,
+dog INT NOT NULL DEFAULT 0 FLAG=1,
+cat INT NOT NULL DEFAULT 0 FLAG=1,
+rabbit INT NOT NULL DEFAULT 0 FLAG=1,
+bird INT NOT NULL DEFAULT 0 FLAG=1,
+fish INT NOT NULL DEFAULT 0 FLAG=1)
+ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
+SELECT * FROM pivet;
+DROP TABLE pivet;
+
+--echo #
+--echo # Testing the "data" column list
+--echo #
+CREATE TABLE pivet (
+name VARCHAR(12) NOT NULL,
+dog INT NOT NULL DEFAULT 0 FLAG=1,
+cat INT NOT NULL DEFAULT 0 FLAG=1)
+ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
+--error ER_GET_ERRMSG
+SELECT * FROM pivet;
+ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1';
+SELECT * FROM pivet;
+DROP TABLE pivet;
+
+--echo #
+--echo # Adding a "dump" column
+--echo #
+CREATE TABLE pivet (
+name VARCHAR(12) NOT NULL,
+dog INT NOT NULL DEFAULT 0 FLAG=1,
+cat INT NOT NULL DEFAULT 0 FLAG=1,
+other INT NOT NULL DEFAULT 0 FLAG=2)
+ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
+SELECT * FROM pivet;
+
+DROP TABLE pivet;
+DROP TABLE pets;
+
+--echo #
+--echo # MDEV-5734
+--echo #
+CREATE TABLE fruit (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(32) DEFAULT NULL,
+ `cnt` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
+INSERT INTO fruit VALUES (1,'apple',1),(2,'banana',1),(3,'apple',2),(4,'cherry',4),(5,'durazno',2);
+SELECT * FROM fruit;
+CREATE TABLE fruit_pivot ENGINE=CONNECT TABLE_TYPE=pivot TABNAME=fruit;
+SELECT * FROM fruit_pivot;
+
+DROP TABLE fruit_pivot;
+DROP TABLE fruit;
+--remove_file $MYSQLD_DATADIR/test/expenses.txt
diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c
index 91b850022fb..e6d452aaf97 100644
--- a/storage/connect/plugutil.c
+++ b/storage/connect/plugutil.c
@@ -153,6 +153,9 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
g->Trace = 0;
g->Createas = 0;
g->Alchecked = 0;
+#if defined(MRRBKA_SUPPORT)
+ g->Mrr = 0;
+#endif // MRRBKA_SUPPORT
g->Activityp = g->ActivityStart = NULL;
g->Xchk = NULL;
strcpy(g->Message, "");
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 564eddbaf2b..9b4f0dbe3ce 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -1144,9 +1144,6 @@ MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
ColUse = U_P;
Nullable = !IS_NOT_NULL(fld->flags);
- if (Buf_Type == TYPE_DECIM)
- Precision = ((Field_new_decimal*)fld)->precision;
-
// Set additional MySQL access method information for column.
Bind = NULL;
To_Val = NULL;
diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp
index bc0dbb9bfc9..ec053357d19 100644
--- a/storage/connect/tabpivot.cpp
+++ b/storage/connect/tabpivot.cpp
@@ -405,7 +405,7 @@ bool TDBPIVOT::GetSourceTable(PGLOBAL g)
strcat(colist, Picol);
// Now we know how much was suballocated
- PlugSubAlloc(g, NULL, strlen(colist));
+ PlugSubAlloc(g, NULL, strlen(colist) + 1);
// Locate the source string (size is not known yet)
Tabsrc = (char*)PlugSubAlloc(g, NULL, 0);
@@ -423,7 +423,7 @@ bool TDBPIVOT::GetSourceTable(PGLOBAL g)
strcat(strcat(Tabsrc, " ORDER BY "), colist);
// Now we know how much was suballocated
- PlugSubAlloc(g, NULL, strlen(Tabsrc));
+ PlugSubAlloc(g, NULL, strlen(Tabsrc) + 1);
} // endif !GBdone
} else if (!Tabsrc) {
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index b778d3f0883..3a48c491cb8 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -147,6 +147,9 @@ bool user_connect::CheckCleanup(void)
g->Xchk = NULL;
g->Createas = 0;
g->Alchecked = 0;
+#if defined(MRRBKA_SUPPORT)
+ g->Mrr = 0;
+#endif // MRRBKA_SUPPORT
last_query_id= thdp->query_id;
if (xtrace)