diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2014-02-27 18:00:01 +0100 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2014-02-27 18:00:01 +0100 |
commit | 43362bc9a005edff28b0470789cd8d9571b022cb (patch) | |
tree | a3f7a12489a41c7d5a8a4b0809d74764966da72b /storage/connect | |
parent | 1699947eef6a73d69ec759b882bebae8bf94fa16 (diff) | |
download | mariadb-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.h | 3 | ||||
-rw-r--r-- | storage/connect/connect.cc | 47 | ||||
-rw-r--r-- | storage/connect/connect.h | 5 | ||||
-rw-r--r-- | storage/connect/global.h | 3 | ||||
-rw-r--r-- | storage/connect/ha_connect.cc | 45 | ||||
-rw-r--r-- | storage/connect/ha_connect.h | 9 | ||||
-rw-r--r-- | storage/connect/mysql-test/connect/r/pivot.result | 27 | ||||
-rw-r--r-- | storage/connect/mysql-test/connect/t/pivot.test | 309 | ||||
-rw-r--r-- | storage/connect/plugutil.c | 3 | ||||
-rw-r--r-- | storage/connect/tabmysql.cpp | 3 | ||||
-rw-r--r-- | storage/connect/tabpivot.cpp | 4 | ||||
-rw-r--r-- | storage/connect/user_connect.cc | 3 |
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) |