summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2013-10-26 17:14:58 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2013-10-26 17:14:58 +0200
commit0f6bcf73de25040c442cec62ddcdbe7f1d43040b (patch)
tree387c8094b935b4518cbf7257648b0ce021528651 /storage
parentba3f4a2cc9ec5337f7677def0a1366cbb7332922 (diff)
downloadmariadb-git-0f6bcf73de25040c442cec62ddcdbe7f1d43040b.tar.gz
- Implement the "exec source" feature for table type MYSQL.
modified: storage/connect/ha_connect.cc storage/connect/myconn.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/ha_connect.cc7
-rw-r--r--storage/connect/myconn.h1
-rw-r--r--storage/connect/tabmysql.cpp212
-rw-r--r--storage/connect/tabmysql.h86
4 files changed, 300 insertions, 6 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index ee2c9a7eea6..b3bafa5a7d9 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -3740,7 +3740,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
{
char spc= ',', qch= 0;
const char *fncn= "?";
- const char *user, *fn, *db, *host, *pwd, *prt, *sep, *tbl, *src, *cnp;
+ const char *user, *fn, *db, *host, *pwd, *prt, *sep, *tbl, *src;
const char *col, *ocl, *rnk, *pic, *fcl;
char *tab, *dsn;
#if defined(WIN32)
@@ -3767,7 +3767,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (!g)
return HA_ERR_INTERNAL_ERROR;
- user= host= pwd= prt= tbl= src= col= ocl= pic= fcl= rnk= cnp= dsn= NULL;
+ user= host= pwd= prt= tbl= src= col= ocl= pic= fcl= rnk= dsn= NULL;
// Get the useful create options
ttp= GetTypeID(topt->type);
@@ -3802,8 +3802,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
cls= GetListOption(g, "class", topt->oplist);
#endif // WIN32
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
- cnp= GetListOption(g, "createopt", topt->oplist);
- cop= (cnp) ? atoi(cnp) : 0;
+ cop= atoi(GetListOption(g, "createopt", topt->oplist, "0"));
} else {
host= "localhost";
user= "root";
diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h
index f8c8c3dcbae..10ff76c3273 100644
--- a/storage/connect/myconn.h
+++ b/storage/connect/myconn.h
@@ -54,6 +54,7 @@ uint GetDefaultPort(void);
class DllItem MYSQLC {
friend class TDBMYSQL;
friend class MYSQLCOL;
+ friend class TDBMYEXC;
// Construction
public:
MYSQLC(void);
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index b1353a47013..28da47d2d33 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -86,6 +86,7 @@ MYSQLDEF::MYSQLDEF(void)
Isview = FALSE;
Bind = FALSE;
Delayed = FALSE;
+ Xsrc = FALSE;
} // end of MYSQLDEF constructor
/***********************************************************************/
@@ -347,6 +348,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
Isview = TRUE;
+ Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
return FALSE;
} // end of DefineAM
@@ -355,7 +357,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE m)
{
- if (Catfunc == FNC_COL)
+ if (Xsrc)
+ return new(g) TDBMYEXC(this);
+ else if (Catfunc == FNC_COL)
return new(g) TDBMCL(this);
else
return new(g) TDBMYSQL(this);
@@ -1280,6 +1284,212 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
} // end of WriteColumn
+/* ------------------------------------------------------------------- */
+
+/***********************************************************************/
+/* Implementation of the TDBMYSQL class. */
+/***********************************************************************/
+
+// Is this really useful ???
+PTDB TDBMYEXC::CopyOne(PTABS t)
+ {
+ PTDB tp;
+ PCOL cp1, cp2;
+ PGLOBAL g = t->G;
+
+ tp = new(g) TDBMYEXC(g, this);
+
+ for (cp1 = Columns; cp1; cp1 = cp1->GetNext()) {
+ cp2 = new(g) MYXCOL((PMYXCOL)cp1, tp);
+
+ NewPointer(t, cp1, cp2);
+ } // endfor cp1
+
+ return tp;
+ } // end of CopyOne
+
+/***********************************************************************/
+/* Allocate MYSQL column description block. */
+/***********************************************************************/
+PCOL TDBMYEXC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
+ {
+ PMYXCOL colp = new(g) MYXCOL(cdp, this, cprec, n);
+
+ if (!colp->Flag)
+ Cmdcol = colp->GetName();
+
+ return colp;
+ } // end of MakeCol
+
+/***********************************************************************/
+/* MakeCMD: make the SQL statement to send to MYSQL connection. */
+/***********************************************************************/
+char *TDBMYEXC::MakeCMD(PGLOBAL g)
+ {
+ char *xcmd = NULL;
+
+ if (To_Filter) {
+ if (Cmdcol) {
+ char col[128], cmd[1024];
+ int n;
+
+ memset(cmd, 0, sizeof(cmd));
+ n = sscanf(To_Filter, "%s = '%1023c", col, cmd);
+
+ if (n == 2 && !stricmp(col, Cmdcol)) {
+ xcmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
+
+ strcpy(xcmd, cmd);
+ xcmd[strlen(xcmd) - 1] = 0;
+ } else
+ strcpy(g->Message, "Invalid command specification filter");
+
+ } else
+ strcpy(g->Message, "No command column in select list");
+
+ } else if (!Srcdef)
+ strcpy(g->Message, "No Srcdef default command");
+ else
+ xcmd = Srcdef;
+
+ return xcmd;
+ } // end of MakeCMD
+
+/***********************************************************************/
+/* EXC GetMaxSize: returns the maximum number of rows in the table. */
+/***********************************************************************/
+int TDBMYEXC::GetMaxSize(PGLOBAL g)
+ {
+ if (MaxSize < 0) {
+ MaxSize = 1;
+ } // endif MaxSize
+
+ return MaxSize;
+ } // end of GetMaxSize
+
+/***********************************************************************/
+/* MySQL Exec Access Method opening routine. */
+/***********************************************************************/
+bool TDBMYEXC::OpenDB(PGLOBAL g)
+ {
+ int rc;
+
+ if (Use == USE_OPEN) {
+ strcpy(g->Message, "Multiple execution is not allowed");
+ return true;
+ } // endif use
+
+ /*********************************************************************/
+ /* Open a MySQL connection for this table. */
+ /* Note: this may not be the proper way to do. Perhaps it is better */
+ /* to test whether a connection is already open for this server */
+ /* and if so to allocate just a new result set. But this only for */
+ /* servers allowing concurency in getting results ??? */
+ /*********************************************************************/
+ if (!Myc.Connected())
+ if (Myc.Open(g, Host, Database, User, Pwd, Port))
+ return true;
+
+ Use = USE_OPEN; // Do it now in case we are recursively called
+
+ if (Mode != MODE_READ) {
+ strcpy(g->Message, "No INSERT/DELETE/UPDATE of MYSQL EXEC tables");
+ return true;
+ } // endif Mode
+
+ /*********************************************************************/
+ /* Get the command to execute. */
+ /*********************************************************************/
+ if (!(Query = MakeCMD(g))) {
+ Myc.Close();
+ return true;
+ } // endif Query
+
+ if ((rc = Myc.ExecSQL(g, Query)) == RC_NF) {
+ strcpy(g->Message, "Affected rows");
+ AftRows = Myc.m_Rows;
+ } else if (rc == RC_OK) {
+ sprintf(g->Message, "Columns and %d rows", Myc.m_Rows);
+ AftRows = Myc.m_Fields;
+ } else
+ return true;
+
+ return false;
+ } // end of OpenDB
+
+/***********************************************************************/
+/* Data Base read routine for MYSQL access method. */
+/***********************************************************************/
+int TDBMYEXC::ReadDB(PGLOBAL g)
+ {
+ return (++N) ? RC_EF : RC_OK;
+ } // end of ReadDB
+
+/***********************************************************************/
+/* WriteDB: Data Base write routine for Exec MYSQL access methods. */
+/***********************************************************************/
+int TDBMYEXC::WriteDB(PGLOBAL g)
+ {
+ strcpy(g->Message, "EXEC MYSQL tables are read only");
+ return RC_FX;
+ } // end of WriteDB
+
+// ------------------------- MYXCOL functions ---------------------------
+
+/***********************************************************************/
+/* MYXCOL public constructor. */
+/***********************************************************************/
+MYXCOL::MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
+ : MYSQLCOL(cdp, tdbp, cprec, i, am)
+ {
+ // Set additional EXEC MYSQL access method information for column.
+ Flag = cdp->GetOffset();
+ } // end of MYSQLCOL constructor
+
+/***********************************************************************/
+/* MYSQLCOL public constructor. */
+/***********************************************************************/
+MYXCOL::MYXCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
+ : MYSQLCOL(fld, tdbp, i, am)
+ {
+ if (trace)
+ htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
+
+ } // end of MYSQLCOL constructor
+
+/***********************************************************************/
+/* MYXCOL constructor used for copying columns. */
+/* tdbp is the pointer to the new table descriptor. */
+/***********************************************************************/
+MYXCOL::MYXCOL(MYXCOL *col1, PTDB tdbp) : MYSQLCOL(col1, tdbp)
+ {
+ Flag = col1->Flag;
+ } // end of MYXCOL copy constructor
+
+/***********************************************************************/
+/* ReadColumn: */
+/***********************************************************************/
+void MYXCOL::ReadColumn(PGLOBAL g)
+ {
+ PTDBMYX tdbp = (PTDBMYX)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;
+ } // endswitch Flag
+
+ } // end of ReadColumn
+
+/***********************************************************************/
+/* WriteColumn: should never be called. */
+/***********************************************************************/
+void MYXCOL::WriteColumn(PGLOBAL g)
+ {
+ assert(false);
+ } // end of WriteColumn
+
/* ---------------------------TDBMCL class --------------------------- */
/***********************************************************************/
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index 2573259ec3c..f4a234526ff 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -3,8 +3,10 @@
typedef class MYSQLDEF *PMYDEF;
typedef class TDBMYSQL *PTDBMY;
-typedef class MYSQLC *PMYC;
typedef class MYSQLCOL *PMYCOL;
+typedef class TDBMYEXC *PTDBMYX;
+typedef class MYXCOL *PMYXCOL;
+typedef class MYSQLC *PMYC;
/* ------------------------- MYSQL classes --------------------------- */
@@ -54,6 +56,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
bool Isview; /* TRUE if this table is a MySQL view */
bool Bind; /* Use prepared statement on insert */
bool Delayed; /* Delayed insert */
+ bool Xsrc; /* Execution type */
}; // end of MYSQLDEF
/***********************************************************************/
@@ -159,6 +162,87 @@ class MYSQLCOL : public COLBLK {
}; // end of class MYSQLCOL
/***********************************************************************/
+/* This is the class declaration for the exec command MYSQL table. */
+/***********************************************************************/
+class TDBMYEXC : public TDBMYSQL {
+ friend class MYXCOL;
+ public:
+ // Constructor
+ TDBMYEXC(PMYDEF tdp) : TDBMYSQL(tdp) {Cmdcol = NULL;}
+ TDBMYEXC(PGLOBAL g, PTDBMYX tdbp) : TDBMYSQL(g, tdbp)
+ {Cmdcol = tdbp->Cmdcol;}
+
+ // Implementation
+//virtual AMT GetAmType(void) {return TYPE_AM_MYSQL;}
+ virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(g, this);}
+
+ // Methods
+ virtual PTDB CopyOne(PTABS t);
+//virtual int GetAffectedRows(void) {return AftRows;}
+//virtual int GetRecpos(void) {return N;}
+//virtual int GetProgMax(PGLOBAL g);
+//virtual void ResetDB(void) {N = 0;}
+//virtual int RowNumber(PGLOBAL g, bool b = FALSE);
+ virtual bool IsView(void) {return Isview;}
+//virtual PSZ GetServer(void) {return Server;}
+// void SetDatabase(LPCSTR db) {Database = (char*)db;}
+
+ // Database routines
+ virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
+ virtual int GetMaxSize(PGLOBAL g);
+ virtual bool OpenDB(PGLOBAL g);
+ virtual int ReadDB(PGLOBAL g);
+ virtual int WriteDB(PGLOBAL g);
+//virtual int DeleteDB(PGLOBAL g, int irc);
+//virtual void CloseDB(PGLOBAL g);
+
+ // Specific routines
+// bool SetColumnRanks(PGLOBAL g);
+// PCOL MakeFieldColumn(PGLOBAL g, char *name);
+// PSZ FindFieldColumn(char *name);
+
+ protected:
+ // Internal functions
+ char *MakeCMD(PGLOBAL g);
+//bool MakeSelect(PGLOBAL g);
+//bool MakeInsert(PGLOBAL g);
+//int BindColumns(PGLOBAL g);
+
+ // Members
+ char *Cmdcol; // The name of the Xsrc command column
+ }; // end of class TDBMYEXC
+
+/***********************************************************************/
+/* Class MYXCOL: MySQL exec command table column. */
+/***********************************************************************/
+class MYXCOL : public MYSQLCOL {
+ friend class TDBMYEXC;
+ public:
+ // Constructors
+ MYXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "MYSQL");
+ MYXCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am = "MYSQL");
+ MYXCOL(MYXCOL *colp, PTDB tdbp); // Constructor used in copy process
+
+ // Implementation
+//virtual int GetAmType(void) {return TYPE_AM_MYSQL;}
+// void InitBind(PGLOBAL g);
+
+ // Methods
+//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
+ virtual void ReadColumn(PGLOBAL g);
+ virtual void WriteColumn(PGLOBAL g);
+// bool FindRank(PGLOBAL g);
+
+ protected:
+ // Default constructor not to be used
+ MYXCOL(void) {}
+
+ // Members
+ char *Buffer; // To get returned message
+ int Flag; // Column content desc
+ }; // end of class MYXCOL
+
+/***********************************************************************/
/* This is the class declaration for the MYSQL column catalog table. */
/***********************************************************************/
class TDBMCL : public TDBCAT {