mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- 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
This commit is contained in:
@@ -3740,7 +3740,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
{
|
{
|
||||||
char spc= ',', qch= 0;
|
char spc= ',', qch= 0;
|
||||||
const char *fncn= "?";
|
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;
|
const char *col, *ocl, *rnk, *pic, *fcl;
|
||||||
char *tab, *dsn;
|
char *tab, *dsn;
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
@@ -3767,7 +3767,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
if (!g)
|
if (!g)
|
||||||
return HA_ERR_INTERNAL_ERROR;
|
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
|
// Get the useful create options
|
||||||
ttp= GetTypeID(topt->type);
|
ttp= GetTypeID(topt->type);
|
||||||
@@ -3802,8 +3802,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
cls= GetListOption(g, "class", topt->oplist);
|
cls= GetListOption(g, "class", topt->oplist);
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
|
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
|
||||||
cnp= GetListOption(g, "createopt", topt->oplist);
|
cop= atoi(GetListOption(g, "createopt", topt->oplist, "0"));
|
||||||
cop= (cnp) ? atoi(cnp) : 0;
|
|
||||||
} else {
|
} else {
|
||||||
host= "localhost";
|
host= "localhost";
|
||||||
user= "root";
|
user= "root";
|
||||||
|
@@ -54,6 +54,7 @@ uint GetDefaultPort(void);
|
|||||||
class DllItem MYSQLC {
|
class DllItem MYSQLC {
|
||||||
friend class TDBMYSQL;
|
friend class TDBMYSQL;
|
||||||
friend class MYSQLCOL;
|
friend class MYSQLCOL;
|
||||||
|
friend class TDBMYEXC;
|
||||||
// Construction
|
// Construction
|
||||||
public:
|
public:
|
||||||
MYSQLC(void);
|
MYSQLC(void);
|
||||||
|
@@ -86,6 +86,7 @@ MYSQLDEF::MYSQLDEF(void)
|
|||||||
Isview = FALSE;
|
Isview = FALSE;
|
||||||
Bind = FALSE;
|
Bind = FALSE;
|
||||||
Delayed = FALSE;
|
Delayed = FALSE;
|
||||||
|
Xsrc = FALSE;
|
||||||
} // end of MYSQLDEF constructor
|
} // end of MYSQLDEF constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -347,6 +348,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
||||||
Isview = TRUE;
|
Isview = TRUE;
|
||||||
|
|
||||||
|
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of DefineAM
|
} // end of DefineAM
|
||||||
|
|
||||||
@@ -355,7 +357,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE m)
|
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);
|
return new(g) TDBMCL(this);
|
||||||
else
|
else
|
||||||
return new(g) TDBMYSQL(this);
|
return new(g) TDBMYSQL(this);
|
||||||
@@ -1280,6 +1284,212 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
|
|||||||
|
|
||||||
} // end of WriteColumn
|
} // 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 --------------------------- */
|
/* ---------------------------TDBMCL class --------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -3,8 +3,10 @@
|
|||||||
|
|
||||||
typedef class MYSQLDEF *PMYDEF;
|
typedef class MYSQLDEF *PMYDEF;
|
||||||
typedef class TDBMYSQL *PTDBMY;
|
typedef class TDBMYSQL *PTDBMY;
|
||||||
typedef class MYSQLC *PMYC;
|
|
||||||
typedef class MYSQLCOL *PMYCOL;
|
typedef class MYSQLCOL *PMYCOL;
|
||||||
|
typedef class TDBMYEXC *PTDBMYX;
|
||||||
|
typedef class MYXCOL *PMYXCOL;
|
||||||
|
typedef class MYSQLC *PMYC;
|
||||||
|
|
||||||
/* ------------------------- MYSQL classes --------------------------- */
|
/* ------------------------- MYSQL classes --------------------------- */
|
||||||
|
|
||||||
@@ -54,6 +56,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
bool Isview; /* TRUE if this table is a MySQL view */
|
bool Isview; /* TRUE if this table is a MySQL view */
|
||||||
bool Bind; /* Use prepared statement on insert */
|
bool Bind; /* Use prepared statement on insert */
|
||||||
bool Delayed; /* Delayed insert */
|
bool Delayed; /* Delayed insert */
|
||||||
|
bool Xsrc; /* Execution type */
|
||||||
}; // end of MYSQLDEF
|
}; // end of MYSQLDEF
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -158,6 +161,87 @@ class MYSQLCOL : public COLBLK {
|
|||||||
int Rank; // Rank (position) number in the query
|
int Rank; // Rank (position) number in the query
|
||||||
}; // end of class MYSQLCOL
|
}; // 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. */
|
/* This is the class declaration for the MYSQL column catalog table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
Reference in New Issue
Block a user