diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2013-10-26 17:14:58 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2013-10-26 17:14:58 +0200 |
commit | 0f6bcf73de25040c442cec62ddcdbe7f1d43040b (patch) | |
tree | 387c8094b935b4518cbf7257648b0ce021528651 /storage | |
parent | ba3f4a2cc9ec5337f7677def0a1366cbb7332922 (diff) | |
download | mariadb-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.cc | 7 | ||||
-rw-r--r-- | storage/connect/myconn.h | 1 | ||||
-rw-r--r-- | storage/connect/tabmysql.cpp | 212 | ||||
-rw-r--r-- | storage/connect/tabmysql.h | 86 |
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 { |