summaryrefslogtreecommitdiff
path: root/storage/connect/taboccur.cpp
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2013-04-29 13:50:20 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2013-04-29 13:50:20 +0200
commit4fd74200dd8ff357b7f870ea0407ef8f3c78ff11 (patch)
treed297698912fdf321efb715957a62ffd2b7e5e099 /storage/connect/taboccur.cpp
parentbc80fb07ded7abcfb99d368d14e4c5e81a669101 (diff)
downloadmariadb-git-4fd74200dd8ff357b7f870ea0407ef8f3c78ff11.tar.gz
- Adding 3 new table types:
PROXY table base on another table. Used by several other types. XCOL proxy on a table having a colummn containing a list of values OCCUR proxy on a table having several columns containing the same type of values that can be put in a unique column and several rows. TBL Not new but now internally using the PROXY table class. - Fix 2 bugs in add_field: Change '=' to ' ' after the COMMENT keyword. Quote column names between '`' in the SQL string. - Update xml test result to the CONNECT version added: storage/connect/taboccur.cpp storage/connect/taboccur.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabxcl.cpp storage/connect/tabxcl.h modified: storage/connect/CMakeLists.txt storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/mycat.cc storage/connect/myconn.cpp storage/connect/mysql-test/connect/r/xml.result storage/connect/plgdbsem.h storage/connect/tabmysql.cpp storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/valblk.cpp storage/connect/valblk.h
Diffstat (limited to 'storage/connect/taboccur.cpp')
-rw-r--r--storage/connect/taboccur.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/storage/connect/taboccur.cpp b/storage/connect/taboccur.cpp
new file mode 100644
index 00000000000..e1b83c06422
--- /dev/null
+++ b/storage/connect/taboccur.cpp
@@ -0,0 +1,375 @@
+/************ TabOccur CPP Declares Source Code File (.CPP) ************/
+/* Name: TABOCCUR.CPP Version 1.0 */
+/* */
+/* (C) Copyright to the author Olivier BERTRAND 2013 */
+/* */
+/* OCCUR: Table that provides a view of a source table where the */
+/* contain of several columns of the source table is placed in only */
+/* one column, the OCCUR column, this resulting into several rows. */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Include relevant section of system dependant header files. */
+/***********************************************************************/
+#include "my_global.h"
+#if defined(WIN32)
+#include <stdlib.h>
+#include <stdio.h>
+#if defined(__BORLANDC__)
+#define __MFC_COMPAT__ // To define min/max as macro
+#endif
+//#include <windows.h>
+#else
+#if defined(UNIX)
+#include <fnmatch.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "osutil.h"
+#else
+//#include <io.h>
+#endif
+//#include <fcntl.h>
+#endif
+
+/***********************************************************************/
+/* Include application header files: */
+/***********************************************************************/
+#include "table.h" // MySQL table definitions
+#include "global.h"
+#include "plgdbsem.h"
+#include "reldef.h"
+#include "filamtxt.h"
+#include "tabdos.h"
+#include "tabcol.h"
+#include "taboccur.h"
+#include "xtable.h"
+#if defined(MYSQL_SUPPORT)
+#include "tabmysql.h"
+#endif // MYSQL_SUPPORT
+#include "ha_connect.h"
+#include "mycat.h"
+
+extern "C" int trace;
+
+/* -------------- Implementation of the OCCUR classes ---------------- */
+
+/***********************************************************************/
+/* DefineAM: define specific AM block values from OCCUR table. */
+/***********************************************************************/
+bool OCCURDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
+ {
+//Tabname = Cat->GetStringCatInfo(g, "SrcTable", "");
+ Xcol = Cat->GetStringCatInfo(g, "OccurCol", "");
+ Rcol = Cat->GetStringCatInfo(g, "RankCol", "");
+ Colist = Cat->GetStringCatInfo(g, "Colist", "");
+ return PRXDEF::DefineAM(g, am, poff);
+ } // end of DefineAM
+
+/***********************************************************************/
+/* GetTable: makes a new TDB of the proper type. */
+/***********************************************************************/
+PTDB OCCURDEF::GetTable(PGLOBAL g, MODE m)
+ {
+ if (Catfunc != FNC_COL) {
+ PTDB tdbp;
+ PTDBOCCUR tocp = new(g) TDBOCCUR(this);
+
+ // Check that the source table is available
+ if (!tocp || !(tdbp = tocp->GetSubTable(g, Tablep)))
+ return NULL;
+
+ // Set Tdbp now
+ tocp->SetTdbp((PTDBASE)tdbp);
+
+ if (tocp->MakeColumnList(g) < 0)
+ return NULL;
+
+ return tocp;
+ } else
+ return new(g) TDBTBC(this);
+
+ } // end of GetTable
+
+/* ------------------------------------------------------------------- */
+
+/***********************************************************************/
+/* Implementation of the TDBOCCUR class. */
+/***********************************************************************/
+TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp)
+ {
+//Tdbp = NULL; // Source table
+ Tabname = tdp->Tablep->GetName(); // Name of source table
+ Colist = tdp->Colist; // List of source columns
+ Xcolumn = tdp->Xcol; // Occur column name
+ Rcolumn = tdp->Rcol; // Rank column name
+ Xcolp = NULL; // To the OCCURCOL column
+ Col = NULL; // To source column blocks array
+ Mult = -1; // Multiplication factor
+ N = 0; // The current table index
+ M = 0; // The occurence rank
+ RowFlag = 0; // 0: Ok, 1: Same, 2: Skip
+ } // end of TDBOCCUR constructor
+
+/***********************************************************************/
+/* Allocate OCCUR/SRC column description block. */
+/***********************************************************************/
+PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
+ {
+ PCOL colp = NULL;
+
+ if (!stricmp(cdp->GetName(), Rcolumn)) {
+ // Allocate a RANK column
+ colp = new(g) RANKCOL(cdp, this, n);
+ } else if (!stricmp(cdp->GetName(), Xcolumn)) {
+ // Allocate the OCCUR column
+ colp = Xcolp = new(g) OCCURCOL(cdp, this, n);
+ } else {
+ colp = new(g) PRXCOL(cdp, this, cprec, n);
+
+ if (((PPRXCOL)colp)->Init(g))
+ return NULL;
+
+ return colp;
+ } //endif name
+
+ if (cprec) {
+ colp->SetNext(cprec->GetNext());
+ cprec->SetNext(colp);
+ } else {
+ colp->SetNext(Columns);
+ Columns = colp;
+ } // endif cprec
+
+ return colp;
+ } // end of MakeCol
+
+/***********************************************************************/
+/* Allocate OCCUR column description block. */
+/***********************************************************************/
+int TDBOCCUR::MakeColumnList(PGLOBAL g)
+ {
+ if (Mult < 0) {
+ char *p, *pn;
+ int i;
+ int n = 0;
+
+ // Count the number of columns and change separator into null char
+ for (pn = Colist; ; pn += (strlen(pn) + 1))
+ if ((p = strchr(pn, ';'))) {
+ *p++ = '\0';
+ n++;
+ } else {
+ if (*pn)
+ n++;
+
+ break;
+ } // endif p
+
+ Col = (PCOL*)PlugSubAlloc(g, NULL, n * sizeof(PCOL));
+
+ for (i = 0, pn = Colist; i < n; i++, pn += (strlen(pn) + 1)) {
+ if (!(Col[i] = Tdbp->ColDB(g, pn, 0))) {
+ // Column not found in table
+ sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname);
+ return -1;
+ } // endif Col
+
+ if (Col[i]->InitValue(g)) {
+ strcpy(g->Message, "OCCUR InitValue failed");
+ return -1;
+ } // endif InitValue
+
+ } // endfor i
+
+ // OCCUR column name defaults to the name of the list first column
+ if (!Xcolumn)
+ Xcolumn = Colist;
+
+ Mult = n;
+ } // endif Mult
+
+ return Mult;
+ } // end of MakeColumnList
+
+/***********************************************************************/
+/* OCCUR GetMaxSize: returns the maximum number of rows in the table. */
+/***********************************************************************/
+int TDBOCCUR::GetMaxSize(PGLOBAL g)
+ {
+ if (MaxSize < 0) {
+// Mult = MakeColumnList(g);
+ MaxSize = Mult * Tdbp->GetMaxSize(g);
+ } // endif MaxSize
+
+ return MaxSize;
+ } // end of GetMaxSize
+
+/***********************************************************************/
+/* In this sample, ROWID will be the (virtual) row number, */
+/* while ROWNUM will be the occurence rank in the multiple column. */
+/***********************************************************************/
+int TDBOCCUR::RowNumber(PGLOBAL g, bool b)
+ {
+ return (b) ? M : N;
+ } // end of RowNumber
+
+/***********************************************************************/
+/* OCCUR Access Method opening routine. */
+/***********************************************************************/
+bool TDBOCCUR::OpenDB(PGLOBAL g)
+ {
+ if (Use == USE_OPEN) {
+ /*******************************************************************/
+ /* Table already open, just replace it at its beginning. */
+ /*******************************************************************/
+ N = M = 0;
+ RowFlag = 0;
+
+ if (Xcolp)
+ Xcolp->Xreset();
+
+ return Tdbp->OpenDB(g);
+ } // endif use
+
+ /*********************************************************************/
+ /* Do it here if not done yet. */
+ /*********************************************************************/
+// if (MakeColumnList(g) < 0)
+// return TRUE;
+
+ if (Mode != MODE_READ) {
+ /*******************************************************************/
+ /* Currently OCCUR tables cannot be modified. */
+ /*******************************************************************/
+ strcpy(g->Message, "OCCUR tables are read only");
+ return TRUE;
+ } // endif Mode
+
+#if 0
+ /*********************************************************************/
+ /* Be sure OCCUR column exist. */
+ /*********************************************************************/
+ if (!Xcolp) {
+ if (!(Xcolp = (POCCURCOL)ColDB(g, Xcolumn, 0))) {
+ sprintf(g->Message, "OCCUR column %s definition error", Xcolumn);
+ return TRUE;
+ } else if (Xcolp->InitValue(g)) {
+ strcpy(g->Message, "OCCUR InitValue failed");
+ return TRUE;
+ } // endif's Xcolp
+
+ } // endif Xcolp
+#endif // 0
+
+ if (Xcolp)
+ // Lock this column so it is evaluated by its table only
+ Xcolp->AddStatus(BUF_READ);
+
+ if (To_Key_Col || To_Kindex) {
+ /*******************************************************************/
+ /* Direct access of OCCUR tables is not implemented yet. */
+ /*******************************************************************/
+ strcpy(g->Message, "No direct access to OCCUR tables");
+ return TRUE;
+ } // endif To_Key_Col
+
+ /*********************************************************************/
+ /* Do open the source table. */
+ /*********************************************************************/
+ return Tdbp->OpenDB(g);
+ } // end of OpenDB
+
+/***********************************************************************/
+/* Data Base read routine for OCCUR access method. */
+/***********************************************************************/
+int TDBOCCUR::ReadDB(PGLOBAL g)
+ {
+ int rc = RC_OK;
+
+ /*********************************************************************/
+ /* Now start the multi reading process. */
+ /*********************************************************************/
+ do {
+ if (RowFlag != 1)
+ if ((rc = Tdbp->ReadDB(g)) != RC_OK)
+ break;
+
+ if (Xcolp) {
+ RowFlag = 0;
+ Xcolp->ReadColumn(g);
+ M = Xcolp->GetI();
+ } // endif Xcolp
+
+ } while (RowFlag == 2);
+
+ N++;
+ return rc;
+ } // end of ReadDB
+
+// ------------------------ OCCURCOL functions ----------------------------
+
+/***********************************************************************/
+/* OCCURCOL public constructor. */
+/***********************************************************************/
+OCCURCOL::OCCURCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n)
+ : COLBLK(cdp, tdbp, n)
+ {
+ // Set additional OCCUR access method information for column.
+ I = 0;
+ } // end of OCCURCOL constructor
+
+/***********************************************************************/
+/* ReadColumn: what this routine does is to access the columns of */
+/* list, extract their value and convert it to buffer type. */
+/***********************************************************************/
+void OCCURCOL::ReadColumn(PGLOBAL g)
+ {
+ PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb;
+ PCOL *col = tdbp->Col;
+
+ for (; I < tdbp->Mult; I++) {
+ col[I]->ReadColumn(g);
+
+ if (Nullable || !col[I]->GetValue()->IsZero())
+ break;
+
+ } // endfor I
+
+ if (I == tdbp->Mult) {
+ // No more values, go to next source row
+ tdbp->RowFlag = 2;
+ I = 0;
+ return;
+ } // endif I
+
+ // Set the OCCUR column value from the Ith source column value
+ Value->SetValue_pval(col[I++]->GetValue());
+ tdbp->RowFlag = 1;
+ } // end of ReadColumn
+
+
+// ------------------------ RANKCOL functions ---------------------------
+
+/***********************************************************************/
+/* ReadColumn: what this routine does is to access the Mth columns of */
+/* list, extract its name and set to it the rank column value. */
+/***********************************************************************/
+void RANKCOL::ReadColumn(PGLOBAL g)
+ {
+ PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb;
+ PCOL *col = tdbp->Col;
+
+ // Set the RANK column value from the Mth source column name
+ if (tdbp->M)
+ Value->SetValue_psz(col[tdbp->M - 1]->GetName());
+ else {
+ Value->Reset();
+
+ if (Nullable)
+ Value->SetNull(true);
+
+ } // endelse
+
+ } // end of ReadColumn