mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
- Allowing views and queries as parameters for PROXY base tables
NOTE: Checking for looping references cannot be done when using views as parameters. This should not be allowed on production servers and should be dependant on a system variable and/or on speciel grant. modified: storage/connect/CMakeLists.txt storage/connect/connect.cc storage/connect/ha_connect.cc storage/connect/myconn.cpp storage/connect/myconn.h storage/connect/mysql-test/connect/r/fmt.result storage/connect/mysql-test/connect/r/pivot.result storage/connect/mysql-test/connect/t/fmt.test storage/connect/mysql-test/connect/t/pivot.test storage/connect/plgdbsem.h storage/connect/plugutil.c storage/connect/tabcol.cpp storage/connect/tabcol.h storage/connect/tabfmt.cpp storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/taboccur.cpp storage/connect/taboccur.h storage/connect/tabpivot.cpp storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/xtable.h
This commit is contained in:
@@ -178,7 +178,7 @@ OPTION(CONNECT_WITH_MYSQL
|
|||||||
|
|
||||||
IF(CONNECT_WITH_MYSQL)
|
IF(CONNECT_WITH_MYSQL)
|
||||||
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
|
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
|
||||||
myconn.cpp myconn.h tabmysql.cpp tabxml.h)
|
myconn.cpp myconn.h tabmysql.cpp tabmysql.h)
|
||||||
add_definitions(-DMYSQL_SUPPORT)
|
add_definitions(-DMYSQL_SUPPORT)
|
||||||
IF(NOT UNIX)
|
IF(NOT UNIX)
|
||||||
#
|
#
|
||||||
|
@@ -71,10 +71,7 @@ int rename_file_ext(const char *from, const char *to,const char *ext);
|
|||||||
PGLOBAL CntExit(PGLOBAL g)
|
PGLOBAL CntExit(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (g) {
|
if (g) {
|
||||||
PDBUSER dup= PlgGetUser(g);
|
|
||||||
|
|
||||||
CntEndDB(g);
|
CntEndDB(g);
|
||||||
free(dup);
|
|
||||||
|
|
||||||
if (g->Activityp)
|
if (g->Activityp)
|
||||||
delete g->Activityp;
|
delete g->Activityp;
|
||||||
@@ -94,13 +91,10 @@ void CntEndDB(PGLOBAL g)
|
|||||||
PDBUSER dbuserp= PlgGetUser(g);
|
PDBUSER dbuserp= PlgGetUser(g);
|
||||||
|
|
||||||
if (dbuserp) {
|
if (dbuserp) {
|
||||||
if (dbuserp->Catalog) {
|
if (dbuserp->Catalog)
|
||||||
delete dbuserp->Catalog;
|
delete dbuserp->Catalog;
|
||||||
dbuserp->Catalog= NULL;
|
|
||||||
} // endif Catalog
|
|
||||||
|
|
||||||
*dbuserp->Name= '\0';
|
free(dbuserp);
|
||||||
// *dbuserp->Work= '\0';
|
|
||||||
} // endif dbuserp
|
} // endif dbuserp
|
||||||
|
|
||||||
} // end of CntEndDB
|
} // end of CntEndDB
|
||||||
@@ -258,10 +252,12 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
|
|||||||
return true;
|
return true;
|
||||||
} // endif tdbp
|
} // endif tdbp
|
||||||
|
|
||||||
if (!c1)
|
if (!c1) {
|
||||||
// Allocate all column blocks for that table
|
if (mode == MODE_INSERT)
|
||||||
tdbp->ColDB(g, NULL, 0);
|
// Allocate all column blocks for that table
|
||||||
else for (p= c1; *p; p+= n) {
|
tdbp->ColDB(g, NULL, 0);
|
||||||
|
|
||||||
|
} else for (p= c1; *p; p+= n) {
|
||||||
// Allocate only used column blocks
|
// Allocate only used column blocks
|
||||||
if (xtrace)
|
if (xtrace)
|
||||||
printf("Allocating column %s\n", p);
|
printf("Allocating column %s\n", p);
|
||||||
|
@@ -696,7 +696,9 @@ bool ha_connect::GetBooleanOption(char *opname, bool bdef)
|
|||||||
char *pv;
|
char *pv;
|
||||||
PTOS options= GetTableOptionStruct(table);
|
PTOS options= GetTableOptionStruct(table);
|
||||||
|
|
||||||
if (!options)
|
if (!stricmp(opname, "View"))
|
||||||
|
opval= (tshp) ? tshp->is_view : table->s->is_view;
|
||||||
|
else if (!options)
|
||||||
;
|
;
|
||||||
else if (!stricmp(opname, "Mapped"))
|
else if (!stricmp(opname, "Mapped"))
|
||||||
opval= options->mapped;
|
opval= options->mapped;
|
||||||
@@ -838,7 +840,7 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
|
|||||||
} else
|
} else
|
||||||
fldp= (tshp) ? tshp->field : table->field;
|
fldp= (tshp) ? tshp->field : table->field;
|
||||||
|
|
||||||
if (!(fp= *fldp))
|
if (!fldp || !(fp= *fldp))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Get the CONNECT field options structure
|
// Get the CONNECT field options structure
|
||||||
@@ -1843,11 +1845,13 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
|
|||||||
|
|
||||||
// Try to get the user if possible
|
// Try to get the user if possible
|
||||||
xp= GetUser(ha_thd(), xp);
|
xp= GetUser(ha_thd(), xp);
|
||||||
PGLOBAL g= xp->g;
|
PGLOBAL g= (xp) ? xp->g : NULL;
|
||||||
|
|
||||||
// Try to set the database environment
|
// Try to set the database environment
|
||||||
if (g)
|
if (g)
|
||||||
rc= (CntCheckDB(g, this, name)) ? (-2) : 0;
|
rc= (CntCheckDB(g, this, name)) ? (-2) : 0;
|
||||||
|
else
|
||||||
|
rc= HA_ERR_INTERNAL_ERROR;
|
||||||
|
|
||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
} // end of open
|
} // end of open
|
||||||
@@ -2809,6 +2813,10 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||||||
bool oldsep= ((PCHK)g->Xchk)->oldsep;
|
bool oldsep= ((PCHK)g->Xchk)->oldsep;
|
||||||
bool newsep= ((PCHK)g->Xchk)->newsep;
|
bool newsep= ((PCHK)g->Xchk)->newsep;
|
||||||
PTDBDOS tdp= (PTDBDOS)(tdbp ? tdbp : GetTDB(g));
|
PTDBDOS tdp= (PTDBDOS)(tdbp ? tdbp : GetTDB(g));
|
||||||
|
|
||||||
|
if (!tdp)
|
||||||
|
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||||
|
|
||||||
PDOSDEF ddp= (PDOSDEF)tdp->GetDef();
|
PDOSDEF ddp= (PDOSDEF)tdp->GetDef();
|
||||||
PIXDEF xp, xp1, xp2, drp=NULL, adp= NULL;
|
PIXDEF xp, xp1, xp2, drp=NULL, adp= NULL;
|
||||||
PIXDEF oldpix= ((PCHK)g->Xchk)->oldpix;
|
PIXDEF oldpix= ((PCHK)g->Xchk)->oldpix;
|
||||||
@@ -3300,7 +3308,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; // *csn;
|
const char *user, *fn, *db, *host, *pwd, *prt, *sep, *tbl, *src;
|
||||||
char *tab, *dsn;
|
char *tab, *dsn;
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
char *nsp= NULL, *cls= NULL;
|
char *nsp= NULL, *cls= NULL;
|
||||||
@@ -3324,16 +3332,17 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
|
|
||||||
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
|
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
|
||||||
|
|
||||||
user= host= pwd= prt= tbl= dsn= NULL;
|
user= host= pwd= prt= tbl= src= dsn= NULL;
|
||||||
|
|
||||||
// Get the useful create options
|
// Get the useful create options
|
||||||
ttp= GetTypeID(topt->type);
|
ttp= GetTypeID(topt->type);
|
||||||
fn= topt->filename;
|
fn= topt->filename;
|
||||||
tab= (char*)topt->tabname;
|
tab= (char*)topt->tabname;
|
||||||
db= topt->dbname;
|
src= topt->srcdef;
|
||||||
|
db= topt->dbname;
|
||||||
fncn= topt->catfunc;
|
fncn= topt->catfunc;
|
||||||
fnc= GetFuncID(fncn);
|
fnc= GetFuncID(fncn);
|
||||||
sep= topt->separator;
|
sep= topt->separator;
|
||||||
spc= (!sep || !strcmp(sep, "\\t")) ? '\t' : *sep;
|
spc= (!sep || !strcmp(sep, "\\t")) ? '\t' : *sep;
|
||||||
qch= topt->qchar ? *topt->qchar : topt->quoted >= 0 ? '"' : 0;
|
qch= topt->qchar ? *topt->qchar : topt->quoted >= 0 ? '"' : 0;
|
||||||
hdr= (int)topt->header;
|
hdr= (int)topt->header;
|
||||||
@@ -3352,25 +3361,20 @@ 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"));
|
||||||
} // endif option_list
|
} else {
|
||||||
|
host= "localhost";
|
||||||
|
user= "root";
|
||||||
|
} // endif option_list
|
||||||
|
|
||||||
if (!db)
|
if (!db)
|
||||||
db= thd->db; // Default value
|
db= thd->db; // Default value
|
||||||
|
|
||||||
// Check table type
|
// Check table type
|
||||||
if (ttp == TAB_UNDEF) {
|
if (ttp == TAB_UNDEF) {
|
||||||
if (!tab) {
|
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
|
||||||
strcpy(g->Message, "No table_type. Was set to DOS");
|
ttp= GetTypeID(topt->type);
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
|
sprintf(g->Message, "No table_type. Was set to %s", topt->type);
|
||||||
ttp= TAB_DOS;
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
|
||||||
topt->type= "DOS";
|
|
||||||
} else {
|
|
||||||
strcpy(g->Message, "No table_type. Was set to PROXY");
|
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
|
|
||||||
ttp= TAB_PRX;
|
|
||||||
topt->type= "PROXY";
|
|
||||||
} // endif fnc
|
|
||||||
|
|
||||||
} else if (ttp == TAB_NIY) {
|
} else if (ttp == TAB_NIY) {
|
||||||
sprintf(g->Message, "Unsupported table type %s", topt->type);
|
sprintf(g->Message, "Unsupported table type %s", topt->type);
|
||||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
@@ -3494,7 +3498,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
else
|
else
|
||||||
return HA_ERR_INTERNAL_ERROR; // Should never happen
|
return HA_ERR_INTERNAL_ERROR; // Should never happen
|
||||||
|
|
||||||
switch (ttp) {
|
if (src && fnc == FNC_NO)
|
||||||
|
qrp= SrcColumns(g, host, db, user, pwd, src, port);
|
||||||
|
else switch (ttp) {
|
||||||
case TAB_DBF:
|
case TAB_DBF:
|
||||||
qrp= DBFColumns(g, fn, fnc == FNC_COL);
|
qrp= DBFColumns(g, fn, fnc == FNC_COL);
|
||||||
break;
|
break;
|
||||||
@@ -3523,7 +3529,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
#if defined(MYSQL_SUPPORT)
|
#if defined(MYSQL_SUPPORT)
|
||||||
case TAB_MYSQL:
|
case TAB_MYSQL:
|
||||||
qrp= MyColumns(g, host, db, user, pwd, tab,
|
qrp= MyColumns(g, host, db, user, pwd, tab,
|
||||||
NULL, port, false, fnc == FNC_COL);
|
NULL, port, fnc == FNC_COL);
|
||||||
break;
|
break;
|
||||||
#endif // MYSQL_SUPPORT
|
#endif // MYSQL_SUPPORT
|
||||||
case TAB_CSV:
|
case TAB_CSV:
|
||||||
@@ -3549,7 +3555,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
return HA_ERR_INTERNAL_ERROR;
|
return HA_ERR_INTERNAL_ERROR;
|
||||||
} // endif qrp
|
} // endif qrp
|
||||||
|
|
||||||
if (fnc != FNC_NO) {
|
if (fnc != FNC_NO || src) {
|
||||||
// Catalog table
|
// Catalog table
|
||||||
for (crp=qrp->Colresp; !b && crp; crp= crp->Next) {
|
for (crp=qrp->Colresp; !b && crp; crp= crp->Next) {
|
||||||
cnm= encode(g, crp->Name);
|
cnm= encode(g, crp->Name);
|
||||||
@@ -3821,13 +3827,23 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
|||||||
case TAB_PRX:
|
case TAB_PRX:
|
||||||
case TAB_XCL:
|
case TAB_XCL:
|
||||||
case TAB_OCCUR:
|
case TAB_OCCUR:
|
||||||
if (!stricmp(options->tabname, create_info->alias) &&
|
if (options->srcdef) {
|
||||||
(!options->dbname || !stricmp(options->dbname, thd->db))) {
|
strcpy(g->Message, "Cannot check looping reference");
|
||||||
sprintf(g->Message, "A %s table cannot refer to itself",
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
|
||||||
options->type);
|
} else if (options->tabname) {
|
||||||
|
if (!stricmp(options->tabname, create_info->alias) &&
|
||||||
|
(!options->dbname || !stricmp(options->dbname, thd->db))) {
|
||||||
|
sprintf(g->Message, "A %s table cannot refer to itself",
|
||||||
|
options->type);
|
||||||
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
|
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||||
|
} // endif tab
|
||||||
|
|
||||||
|
} else {
|
||||||
|
strcpy(g->Message, "Missing object table name or definition");
|
||||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
return HA_ERR_INTERNAL_ERROR;
|
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||||
} // endif tab
|
} // endif tabname
|
||||||
|
|
||||||
} // endswitch ttp
|
} // endswitch ttp
|
||||||
|
|
||||||
|
@@ -66,13 +66,13 @@ extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
|
|||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* MyColumns: constructs the result blocks containing all columns */
|
/* MyColumns: constructs the result blocks containing all columns */
|
||||||
/* of a MySQL table that will be retrieved by GetData commands. */
|
/* of a MySQL table or view. */
|
||||||
/* key = TRUE when called from Create Table to get key informations. */
|
/* info = TRUE to get catalog column informations. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
||||||
const char *user, const char *pwd,
|
const char *user, const char *pwd,
|
||||||
const char *table, const char *colpat,
|
const char *table, const char *colpat,
|
||||||
int port, bool key, bool info)
|
int port, bool info)
|
||||||
{
|
{
|
||||||
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
|
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
|
||||||
TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT,
|
TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT,
|
||||||
@@ -124,9 +124,6 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
length[0] = 128;
|
length[0] = 128;
|
||||||
} // endif info
|
} // endif info
|
||||||
|
|
||||||
//if (!key) // We are not called from Create table
|
|
||||||
// ncol--; // No date format column yet
|
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Allocate the structures used to refer to the result set. */
|
/* Allocate the structures used to refer to the result set. */
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
@@ -219,6 +216,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
crp->Kdata->SetValue(fld, i);
|
crp->Kdata->SetValue(fld, i);
|
||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (k > 1) {
|
if (k > 1) {
|
||||||
// Multicolumn primary key
|
// Multicolumn primary key
|
||||||
PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata;
|
PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata;
|
||||||
@@ -228,6 +226,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
vbp->SetValue(k, i);
|
vbp->SetValue(k, i);
|
||||||
|
|
||||||
} // endif k
|
} // endif k
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Close MySQL connection. */
|
/* Close MySQL connection. */
|
||||||
@@ -240,6 +239,33 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
return qrp;
|
return qrp;
|
||||||
} // end of MyColumns
|
} // end of MyColumns
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* SrcColumns: constructs the result blocks containing all columns */
|
||||||
|
/* resulting from an SQL source definition query execution. */
|
||||||
|
/************************************************************************/
|
||||||
|
PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
|
||||||
|
const char *user, const char *pwd,
|
||||||
|
const char *srcdef, int port)
|
||||||
|
{
|
||||||
|
int w;
|
||||||
|
MYSQLC myc;
|
||||||
|
PQRYRES qrp = NULL;
|
||||||
|
|
||||||
|
if (!port)
|
||||||
|
port = mysqld_port;
|
||||||
|
|
||||||
|
// Open a MySQL connection for this table
|
||||||
|
if (myc.Open(g, host, db, user, pwd, port))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Send the source command to MySQL
|
||||||
|
if (myc.ExecSQL(g, srcdef, &w) == RC_OK)
|
||||||
|
qrp = myc.GetResult(g);
|
||||||
|
|
||||||
|
myc.Close();
|
||||||
|
return qrp;
|
||||||
|
} // end of SrcColumns
|
||||||
|
|
||||||
/* -------------------------- Class MYSQLC --------------------------- */
|
/* -------------------------- Class MYSQLC --------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -38,7 +38,11 @@ typedef class MYSQLC *PMYC;
|
|||||||
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
||||||
const char *user, const char *pwd,
|
const char *user, const char *pwd,
|
||||||
const char *table, const char *colpat,
|
const char *table, const char *colpat,
|
||||||
int port, bool key, bool info);
|
int port, bool info);
|
||||||
|
|
||||||
|
PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
|
||||||
|
const char *user, const char *pwd,
|
||||||
|
const char *srcdef, int port);
|
||||||
|
|
||||||
/* -------------------------- MYCONN class --------------------------- */
|
/* -------------------------- MYCONN class --------------------------- */
|
||||||
|
|
||||||
@@ -47,6 +51,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class DllItem MYSQLC {
|
class DllItem MYSQLC {
|
||||||
friend class TDBMYSQL;
|
friend class TDBMYSQL;
|
||||||
|
friend class MYSQLCOL;
|
||||||
// Construction
|
// Construction
|
||||||
public:
|
public:
|
||||||
MYSQLC(void);
|
MYSQLC(void);
|
||||||
|
@@ -18,7 +18,7 @@ CREATE TABLE t1
|
|||||||
id INT NOT NULL field_format=' %n%d%n'
|
id INT NOT NULL field_format=' %n%d%n'
|
||||||
) ENGINE=CONNECT TABLE_TYPE=FMT FILE_NAME='t1.txt';
|
) ENGINE=CONNECT TABLE_TYPE=FMT FILE_NAME='t1.txt';
|
||||||
INSERT INTO t1 VALUES (10),(20);
|
INSERT INTO t1 VALUES (10),(20);
|
||||||
ERROR HY000: Got error 122 'Writing FMT files is not implemented yet' from CONNECT
|
ERROR HY000: Got error 174 'Writing FMT files is not implemented yet' from CONNECT
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# Testing manual examples
|
# Testing manual examples
|
||||||
@@ -59,7 +59,7 @@ ID NAME DEPNO SALARY
|
|||||||
56 POIROT-DELMOTTE 0 18009.00
|
56 POIROT-DELMOTTE 0 18009.00
|
||||||
345 67 19000.25
|
345 67 19000.25
|
||||||
UPDATE t1 SET SALARY=1234;
|
UPDATE t1 SET SALARY=1234;
|
||||||
ERROR HY000: Got error 122 'Writing FMT files is not implemented yet' from CONNECT
|
ERROR HY000: Got error 174 'Writing FMT files is not implemented yet' from CONNECT
|
||||||
DELETE FROM t1 WHERE ID=56;
|
DELETE FROM t1 WHERE ID=56;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
ID NAME DEPNO SALARY
|
ID NAME DEPNO SALARY
|
||||||
|
@@ -77,8 +77,8 @@ Beer DOUBLE(8,2) FLAG=1,
|
|||||||
Car DOUBLE(8,2) FLAG=1,
|
Car DOUBLE(8,2) FLAG=1,
|
||||||
Food DOUBLE(8,2) FLAG=1)
|
Food DOUBLE(8,2) FLAG=1)
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
||||||
SRCDEF='select who, week, what, sum(amount) from expenses where week in (4,5) group by who, week, what';
|
SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what';
|
||||||
ALTER TABLE pivex OPTION_LIST='port=PORT';
|
ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=PORT';
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||||
SELECT * FROM pivex;
|
SELECT * FROM pivex;
|
||||||
@@ -125,7 +125,7 @@ Middle DOUBLE(8,2) FLAG=1,
|
|||||||
Last DOUBLE(8,2) FLAG=1)
|
Last DOUBLE(8,2) FLAG=1)
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
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';
|
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';
|
||||||
ALTER TABLE pivex OPTION_LIST='PivotCol=wk,port=PORT';
|
ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=PORT';
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||||
SELECT * FROM pivex;
|
SELECT * FROM pivex;
|
||||||
|
@@ -1,85 +1,85 @@
|
|||||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||||
--copy_file $MTR_SUITE_DIR/std_data/funny.txt $MYSQLD_DATADIR/test/funny.txt
|
--copy_file $MTR_SUITE_DIR/std_data/funny.txt $MYSQLD_DATADIR/test/funny.txt
|
||||||
--copy_file $MTR_SUITE_DIR/std_data/funny2.txt $MYSQLD_DATADIR/test/funny2.txt
|
--copy_file $MTR_SUITE_DIR/std_data/funny2.txt $MYSQLD_DATADIR/test/funny2.txt
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Testing errors
|
--echo # Testing errors
|
||||||
--echo #
|
--echo #
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
ID INT NOT NULL field_format=' %n%d%n'
|
ID INT NOT NULL field_format=' %n%d%n'
|
||||||
) Engine=CONNECT table_type=FMT file_name='nonexistent.txt';
|
) Engine=CONNECT table_type=FMT file_name='nonexistent.txt';
|
||||||
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
|
--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
|
||||||
# TODO: check why this is needed for Windows
|
# TODO: check why this is needed for Windows
|
||||||
--replace_result Open(rt) Open(rb)
|
--replace_result Open(rt) Open(rb)
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Testing update on FMT tables
|
--echo # Testing update on FMT tables
|
||||||
--echo #
|
--echo #
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
id INT NOT NULL field_format=' %n%d%n'
|
id INT NOT NULL field_format=' %n%d%n'
|
||||||
) ENGINE=CONNECT TABLE_TYPE=FMT FILE_NAME='t1.txt';
|
) ENGINE=CONNECT TABLE_TYPE=FMT FILE_NAME='t1.txt';
|
||||||
--error ER_GET_ERRMSG
|
--error ER_GET_ERRMSG
|
||||||
INSERT INTO t1 VALUES (10),(20);
|
INSERT INTO t1 VALUES (10),(20);
|
||||||
# TODO:
|
# TODO:
|
||||||
#--error ER_GET_ERRMSG
|
#--error ER_GET_ERRMSG
|
||||||
#UPDATE t1 SET id=20;
|
#UPDATE t1 SET id=20;
|
||||||
#TRUNCATE TABLE t1;
|
#TRUNCATE TABLE t1;
|
||||||
#DELETE FROM t1 WHERE id=10;
|
#DELETE FROM t1 WHERE id=10;
|
||||||
#SELECT * FROM t1;
|
#SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--remove_file $MYSQLD_DATADIR/test/t1.txt
|
#--remove_file $MYSQLD_DATADIR/test/t1.txt
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Testing manual examples
|
--echo # Testing manual examples
|
||||||
--echo #
|
--echo #
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
ID Integer(5) not null field_format=' %n%d%n',
|
ID Integer(5) not null field_format=' %n%d%n',
|
||||||
NAME Char(16) not null field_format=" , '%n%[^']%n'",
|
NAME Char(16) not null field_format=" , '%n%[^']%n'",
|
||||||
DEPNO Integer(4) not null field_format=' , #%n%d%n',
|
DEPNO Integer(4) not null field_format=' , #%n%d%n',
|
||||||
SALARY Double(12,2) not null field_format=' ; %n%f%n'
|
SALARY Double(12,2) not null field_format=' ; %n%f%n'
|
||||||
) Engine=CONNECT table_type=FMT file_name='funny.txt';
|
) Engine=CONNECT table_type=FMT file_name='funny.txt';
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# TODO: shoudn't a warning instead of error be returned on bad format?
|
# TODO: shoudn't a warning instead of error be returned on bad format?
|
||||||
#
|
#
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
ID Integer(5) not null field_format=' %n%d%n',
|
ID Integer(5) not null field_format=' %n%d%n',
|
||||||
NAME Char(16) not null field_format=" , '%n%[^']%n'",
|
NAME Char(16) not null field_format=" , '%n%[^']%n'",
|
||||||
DEPNO Integer(4) not null field_format=' , #%n%d%n',
|
DEPNO Integer(4) not null field_format=' , #%n%d%n',
|
||||||
SALARY Double(12,2) not null field_format=' ; %n%f%n'
|
SALARY Double(12,2) not null field_format=' ; %n%f%n'
|
||||||
) Engine=CONNECT table_type=FMT file_name='funny2.txt';
|
) Engine=CONNECT table_type=FMT file_name='funny2.txt';
|
||||||
--error ER_GET_ERRMSG
|
--error ER_GET_ERRMSG
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
ID Integer(5) not null field_format=' %n%d%n',
|
ID Integer(5) not null field_format=' %n%d%n',
|
||||||
NAME Char(16) not null field_format=' , ''%n%[^'']%m',
|
NAME Char(16) not null field_format=' , ''%n%[^'']%m',
|
||||||
DEPNO Integer(4) not null field_format=''' , #%n%d%m',
|
DEPNO Integer(4) not null field_format=''' , #%n%d%m',
|
||||||
SALARY Double(12,2) not null field_format=' ; %n%f%n'
|
SALARY Double(12,2) not null field_format=' ; %n%f%n'
|
||||||
) Engine=CONNECT table_type=FMT file_name='funny2.txt';
|
) Engine=CONNECT table_type=FMT file_name='funny2.txt';
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_GET_ERRMSG
|
||||||
UPDATE t1 SET SALARY=1234;
|
UPDATE t1 SET SALARY=1234;
|
||||||
# TODO: this query crashes
|
# TODO: this query crashes
|
||||||
# UPDATE t1 SET SALARY=1234 WHERE ID=56;
|
# UPDATE t1 SET SALARY=1234 WHERE ID=56;
|
||||||
DELETE FROM t1 WHERE ID=56;
|
DELETE FROM t1 WHERE ID=56;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Clean up
|
# Clean up
|
||||||
#
|
#
|
||||||
--remove_file $MYSQLD_DATADIR/test/funny.txt
|
--remove_file $MYSQLD_DATADIR/test/funny.txt
|
||||||
--remove_file $MYSQLD_DATADIR/test/funny2.txt
|
--remove_file $MYSQLD_DATADIR/test/funny2.txt
|
||||||
|
@@ -1,144 +1,145 @@
|
|||||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||||
let $PORT= `select @@port`;
|
let $PORT= `select @@port`;
|
||||||
--copy_file $MTR_SUITE_DIR/std_data/expenses.txt $MYSQLD_DATADIR/test/expenses.txt
|
--copy_file $MTR_SUITE_DIR/std_data/expenses.txt $MYSQLD_DATADIR/test/expenses.txt
|
||||||
|
--copy_file $MTR_SUITE_DIR/std_data/connect.ini $MYSQLD_DATADIR/test/connect.ini
|
||||||
--echo #
|
|
||||||
--echo # Testing the PIVOT table type
|
--echo #
|
||||||
--echo #
|
--echo # Testing the PIVOT table type
|
||||||
CREATE TABLE expenses (
|
--echo #
|
||||||
Who CHAR(10) NOT NULL,
|
CREATE TABLE expenses (
|
||||||
Week INT(2) NOT NULL,
|
Who CHAR(10) NOT NULL,
|
||||||
What CHAR(12) NOT NULL,
|
Week INT(2) NOT NULL,
|
||||||
Amount DOUBLE(8,2))
|
What CHAR(12) NOT NULL,
|
||||||
ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='expenses.txt' ENDING=2;
|
Amount DOUBLE(8,2))
|
||||||
SELECT * FROM expenses;
|
ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='expenses.txt' ENDING=2;
|
||||||
|
SELECT * FROM expenses;
|
||||||
--echo #
|
|
||||||
--echo # Pivoting from What
|
--echo #
|
||||||
--echo #
|
--echo # Pivoting from What
|
||||||
CREATE TABLE pivex (
|
--echo #
|
||||||
Who CHAR(10) NOT NULL,
|
CREATE TABLE pivex (
|
||||||
Week INT(2) NOT NULL,
|
Who CHAR(10) NOT NULL,
|
||||||
Beer DOUBLE(8,2) FLAG=1,
|
Week INT(2) NOT NULL,
|
||||||
Car DOUBLE(8,2) FLAG=1,
|
Beer DOUBLE(8,2) FLAG=1,
|
||||||
Food DOUBLE(8,2) FLAG=1)
|
Car DOUBLE(8,2) FLAG=1,
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
|
Food DOUBLE(8,2) FLAG=1)
|
||||||
--replace_result $PORT PORT
|
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
|
||||||
--eval ALTER TABLE pivex OPTION_LIST='port=$PORT'
|
--replace_result $PORT PORT
|
||||||
SELECT * FROM pivex;
|
--eval ALTER TABLE pivex OPTION_LIST='port=$PORT'
|
||||||
|
SELECT * FROM pivex;
|
||||||
--echo #
|
|
||||||
--echo # Restricting the columns in a Pivot Table
|
--echo #
|
||||||
--echo #
|
--echo # Restricting the columns in a Pivot Table
|
||||||
ALTER TABLE pivex DROP COLUMN week;
|
--echo #
|
||||||
SELECT * FROM pivex;
|
ALTER TABLE pivex DROP COLUMN week;
|
||||||
|
SELECT * FROM pivex;
|
||||||
--echo #
|
|
||||||
--echo # Using a source definition
|
--echo #
|
||||||
--echo #
|
--echo # Using a source definition
|
||||||
DROP TABLE pivex;
|
--echo #
|
||||||
CREATE TABLE pivex (
|
DROP TABLE pivex;
|
||||||
Who CHAR(10) NOT NULL,
|
CREATE TABLE pivex (
|
||||||
Week INT(2) NOT NULL,
|
Who CHAR(10) NOT NULL,
|
||||||
Beer DOUBLE(8,2) FLAG=1,
|
Week INT(2) NOT NULL,
|
||||||
Car DOUBLE(8,2) FLAG=1,
|
Beer DOUBLE(8,2) FLAG=1,
|
||||||
Food DOUBLE(8,2) FLAG=1)
|
Car DOUBLE(8,2) FLAG=1,
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
Food DOUBLE(8,2) FLAG=1)
|
||||||
SRCDEF='select who, week, what, sum(amount) from expenses where week in (4,5) group by who, week, what';
|
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
||||||
--replace_result $PORT PORT
|
SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what';
|
||||||
--eval ALTER TABLE pivex OPTION_LIST='port=$PORT'
|
--replace_result $PORT PORT
|
||||||
SELECT * FROM pivex;
|
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=$PORT'
|
||||||
|
SELECT * FROM pivex;
|
||||||
--echo #
|
|
||||||
--echo # Pivoting from Week
|
--echo #
|
||||||
--echo #
|
--echo # Pivoting from Week
|
||||||
DROP TABLE pivex;
|
--echo #
|
||||||
CREATE TABLE pivex (
|
DROP TABLE pivex;
|
||||||
Who CHAR(10) NOT NULL,
|
CREATE TABLE pivex (
|
||||||
What CHAR(12) NOT NULL,
|
Who CHAR(10) NOT NULL,
|
||||||
`3` DOUBLE(8,2) FLAG=1,
|
What CHAR(12) NOT NULL,
|
||||||
`4` DOUBLE(8,2) FLAG=1,
|
`3` DOUBLE(8,2) FLAG=1,
|
||||||
`5` DOUBLE(8,2) FLAG=1)
|
`4` DOUBLE(8,2) FLAG=1,
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
|
`5` DOUBLE(8,2) FLAG=1)
|
||||||
--replace_result $PORT PORT
|
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
|
||||||
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=$PORT'
|
--replace_result $PORT PORT
|
||||||
SELECT * FROM pivex;
|
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=$PORT'
|
||||||
|
SELECT * FROM pivex;
|
||||||
--echo #
|
|
||||||
--echo # Using scalar functions and expresssions
|
--echo #
|
||||||
--echo #
|
--echo # Using scalar functions and expresssions
|
||||||
DROP TABLE pivex;
|
--echo #
|
||||||
CREATE TABLE pivex (
|
DROP TABLE pivex;
|
||||||
Who CHAR(10) NOT NULL,
|
CREATE TABLE pivex (
|
||||||
What CHAR(12) NOT NULL,
|
Who CHAR(10) NOT NULL,
|
||||||
First DOUBLE(8,2) FLAG=1,
|
What CHAR(12) NOT NULL,
|
||||||
Middle DOUBLE(8,2) FLAG=1,
|
First DOUBLE(8,2) FLAG=1,
|
||||||
Last DOUBLE(8,2) FLAG=1)
|
Middle DOUBLE(8,2) FLAG=1,
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
Last DOUBLE(8,2) FLAG=1)
|
||||||
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';
|
ENGINE=CONNECT TABLE_TYPE=PIVOT
|
||||||
--replace_result $PORT PORT
|
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';
|
||||||
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=wk,port=$PORT'
|
--replace_result $PORT PORT
|
||||||
SELECT * FROM pivex;
|
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=$PORT'
|
||||||
DROP TABLE pivex;
|
SELECT * FROM pivex;
|
||||||
DROP TABLE expenses;
|
DROP TABLE pivex;
|
||||||
|
DROP TABLE expenses;
|
||||||
--echo #
|
|
||||||
--echo # Make the PETS table
|
--echo #
|
||||||
--echo #
|
--echo # Make the PETS table
|
||||||
CREATE TABLE pets (
|
--echo #
|
||||||
Name VARCHAR(12) NOT NULL,
|
CREATE TABLE pets (
|
||||||
Race CHAR(6) NOT NULL,
|
Name VARCHAR(12) NOT NULL,
|
||||||
Number INT NOT NULL) ENGINE=MYISAM;
|
Race CHAR(6) NOT NULL,
|
||||||
INSERT INTO pets VALUES('John','dog',2);
|
Number INT NOT NULL) ENGINE=MYISAM;
|
||||||
INSERT INTO pets VALUES('Bill','cat',1);
|
INSERT INTO pets VALUES('John','dog',2);
|
||||||
INSERT INTO pets VALUES('Mary','dog',1);
|
INSERT INTO pets VALUES('Bill','cat',1);
|
||||||
INSERT INTO pets VALUES('Mary','cat',1);
|
INSERT INTO pets VALUES('Mary','dog',1);
|
||||||
INSERT INTO pets VALUES('Lisbeth','rabbit',2);
|
INSERT INTO pets VALUES('Mary','cat',1);
|
||||||
INSERT INTO pets VALUES('Kevin','cat',2);
|
INSERT INTO pets VALUES('Lisbeth','rabbit',2);
|
||||||
INSERT INTO pets VALUES('Kevin','bird',6);
|
INSERT INTO pets VALUES('Kevin','cat',2);
|
||||||
INSERT INTO pets VALUES('Donald','dog',1);
|
INSERT INTO pets VALUES('Kevin','bird',6);
|
||||||
INSERT INTO pets VALUES('Donald','fish',3);
|
INSERT INTO pets VALUES('Donald','dog',1);
|
||||||
SELECT * FROM pets;
|
INSERT INTO pets VALUES('Donald','fish',3);
|
||||||
|
SELECT * FROM pets;
|
||||||
--echo #
|
|
||||||
--echo # Pivot the PETS table
|
--echo #
|
||||||
--echo #
|
--echo # Pivot the PETS table
|
||||||
CREATE TABLE pivet (
|
--echo #
|
||||||
name VARCHAR(12) NOT NULL,
|
CREATE TABLE pivet (
|
||||||
dog INT NOT NULL DEFAULT 0 FLAG=1,
|
name VARCHAR(12) NOT NULL,
|
||||||
cat INT NOT NULL DEFAULT 0 FLAG=1,
|
dog INT NOT NULL DEFAULT 0 FLAG=1,
|
||||||
rabbit INT NOT NULL DEFAULT 0 FLAG=1,
|
cat INT NOT NULL DEFAULT 0 FLAG=1,
|
||||||
bird INT NOT NULL DEFAULT 0 FLAG=1,
|
rabbit INT NOT NULL DEFAULT 0 FLAG=1,
|
||||||
fish INT NOT NULL DEFAULT 0 FLAG=1)
|
bird INT NOT NULL DEFAULT 0 FLAG=1,
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
|
fish INT NOT NULL DEFAULT 0 FLAG=1)
|
||||||
SELECT * FROM pivet;
|
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
|
||||||
DROP TABLE pivet;
|
SELECT * FROM pivet;
|
||||||
|
DROP TABLE pivet;
|
||||||
--echo #
|
|
||||||
--echo # Testing the "data" column list
|
--echo #
|
||||||
--echo #
|
--echo # Testing the "data" column list
|
||||||
CREATE TABLE pivet (
|
--echo #
|
||||||
name VARCHAR(12) NOT NULL,
|
CREATE TABLE pivet (
|
||||||
dog INT NOT NULL DEFAULT 0 FLAG=1,
|
name VARCHAR(12) NOT NULL,
|
||||||
cat INT NOT NULL DEFAULT 0 FLAG=1)
|
dog INT NOT NULL DEFAULT 0 FLAG=1,
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
|
cat INT NOT NULL DEFAULT 0 FLAG=1)
|
||||||
--error ER_GET_ERRMSG
|
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
|
||||||
SELECT * FROM pivet;
|
--error ER_GET_ERRMSG
|
||||||
ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1';
|
SELECT * FROM pivet;
|
||||||
SELECT * FROM pivet;
|
ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1';
|
||||||
DROP TABLE pivet;
|
SELECT * FROM pivet;
|
||||||
|
DROP TABLE pivet;
|
||||||
--echo #
|
|
||||||
--echo # Adding a "dump" column
|
--echo #
|
||||||
--echo #
|
--echo # Adding a "dump" column
|
||||||
CREATE TABLE pivet (
|
--echo #
|
||||||
name VARCHAR(12) NOT NULL,
|
CREATE TABLE pivet (
|
||||||
dog INT NOT NULL DEFAULT 0 FLAG=1,
|
name VARCHAR(12) NOT NULL,
|
||||||
cat INT NOT NULL DEFAULT 0 FLAG=1,
|
dog INT NOT NULL DEFAULT 0 FLAG=1,
|
||||||
other INT NOT NULL DEFAULT 0 FLAG=2)
|
cat INT NOT NULL DEFAULT 0 FLAG=1,
|
||||||
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
|
other INT NOT NULL DEFAULT 0 FLAG=2)
|
||||||
SELECT * FROM pivet;
|
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
|
||||||
|
SELECT * FROM pivet;
|
||||||
DROP TABLE pivet;
|
|
||||||
DROP TABLE pets;
|
DROP TABLE pivet;
|
||||||
--remove_file $MYSQLD_DATADIR/test/expenses.txt
|
DROP TABLE pets;
|
||||||
|
--remove_file $MYSQLD_DATADIR/test/expenses.txt
|
||||||
|
@@ -24,8 +24,8 @@
|
|||||||
#define DOS_BUFF_LEN 100 /* Number of lines in binary file buffer */
|
#define DOS_BUFF_LEN 100 /* Number of lines in binary file buffer */
|
||||||
#undef DOMAIN /* For Unix version */
|
#undef DOMAIN /* For Unix version */
|
||||||
|
|
||||||
enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Correl Block */
|
enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Srcdef/... Block */
|
||||||
TYPE_COLUMN = 51, /* Column Name/Correl Block */
|
TYPE_COLUMN = 51, /* Column Name/Qualifier Block */
|
||||||
// TYPE_OPVAL = 52, /* Operator value (OPVAL) */
|
// TYPE_OPVAL = 52, /* Operator value (OPVAL) */
|
||||||
TYPE_TDB = 53, /* Table Description Block */
|
TYPE_TDB = 53, /* Table Description Block */
|
||||||
TYPE_COLBLK = 54, /* Column Description Block */
|
TYPE_COLBLK = 54, /* Column Description Block */
|
||||||
|
@@ -147,6 +147,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
|
|||||||
|
|
||||||
if (!(g = malloc(sizeof(GLOBAL)))) {
|
if (!(g = malloc(sizeof(GLOBAL)))) {
|
||||||
fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
|
fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
|
||||||
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
g->Sarea_Size = worksize;
|
g->Sarea_Size = worksize;
|
||||||
g->Trace = 0;
|
g->Trace = 0;
|
||||||
@@ -180,7 +181,9 @@ int PlugExit(PGLOBAL g)
|
|||||||
if (!g)
|
if (!g)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
free(g->Sarea);
|
if (g->Sarea)
|
||||||
|
free(g->Sarea);
|
||||||
|
|
||||||
free(g);
|
free(g);
|
||||||
return rc;
|
return rc;
|
||||||
} /* end of PlugExit */
|
} /* end of PlugExit */
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/************* TabCol C++ Functions Source Code File (.CPP) ************/
|
/************* TabCol C++ Functions Source Code File (.CPP) ************/
|
||||||
/* Name: TABCOL.CPP Version 2.6 */
|
/* Name: TABCOL.CPP Version 2.7 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 1998-2012 */
|
/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */
|
||||||
/* */
|
/* */
|
||||||
/* This file contains the PlugDB++ XTAB, COLUMN and XORDER methods. */
|
/* This file contains the PlugDB++ XTAB, COLUMN and XORDER methods. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -23,18 +23,18 @@
|
|||||||
#include "tabcol.h"
|
#include "tabcol.h"
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* XTAB public constructor (in which Correl defaults to Name). */
|
/* XTAB public constructor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
XTAB::XTAB(LPCSTR name, LPCSTR correl) : Name(name)
|
XTAB::XTAB(LPCSTR name, LPCSTR srcdef) : Name(name)
|
||||||
{
|
{
|
||||||
Next = NULL;
|
Next = NULL;
|
||||||
To_Tdb = NULL;
|
To_Tdb = NULL;
|
||||||
Correl = (correl) ? correl : name;
|
Srcdef = srcdef;
|
||||||
Creator = NULL;
|
Creator = NULL;
|
||||||
Qualifier = NULL;
|
Qualifier = NULL;
|
||||||
|
|
||||||
#ifdef DEBTRACE
|
#ifdef DEBTRACE
|
||||||
htrc(" making new TABLE %s %s\n", Name, Correl);
|
htrc(" making new TABLE %s %s\n", Name, Srcdef);
|
||||||
#endif
|
#endif
|
||||||
} // end of XTAB constructor
|
} // end of XTAB constructor
|
||||||
|
|
||||||
@@ -45,12 +45,12 @@ XTAB::XTAB(PTABLE tp) : Name(tp->Name)
|
|||||||
{
|
{
|
||||||
Next = NULL;
|
Next = NULL;
|
||||||
To_Tdb = NULL;
|
To_Tdb = NULL;
|
||||||
Correl = tp->Correl;
|
Srcdef = tp->Srcdef;
|
||||||
Creator = tp->Creator;
|
Creator = tp->Creator;
|
||||||
Qualifier = tp->Qualifier;
|
Qualifier = tp->Qualifier;
|
||||||
|
|
||||||
#ifdef DEBTRACE
|
#ifdef DEBTRACE
|
||||||
htrc(" making copy TABLE %s %s\n", Name, Correl);
|
htrc(" making copy TABLE %s %s\n", Name, Srcdef);
|
||||||
#endif
|
#endif
|
||||||
} // end of XTAB constructor
|
} // end of XTAB constructor
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ void XTAB::Print(PGLOBAL g, FILE *f, uint n)
|
|||||||
|
|
||||||
for (PTABLE tp = this; tp; tp = tp->Next) {
|
for (PTABLE tp = this; tp; tp = tp->Next) {
|
||||||
fprintf(f, "%sTABLE: %s.%s %s\n",
|
fprintf(f, "%sTABLE: %s.%s %s\n",
|
||||||
m, SVP(tp->Creator), tp->Name, SVP(tp->Correl));
|
m, SVP(tp->Creator), tp->Name, SVP(tp->Srcdef));
|
||||||
PlugPutOut(g, f, TYPE_TDB, tp->To_Tdb, n + 2);
|
PlugPutOut(g, f, TYPE_TDB, tp->To_Tdb, n + 2);
|
||||||
} /* endfor tp */
|
} /* endfor tp */
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ void XTAB::Print(PGLOBAL g, char *ps, uint z)
|
|||||||
|
|
||||||
for (PTABLE tp = this; tp && n > 0; tp = tp->Next) {
|
for (PTABLE tp = this; tp && n > 0; tp = tp->Next) {
|
||||||
i = sprintf(buf, "TABLE: %s.%s %s To_Tdb=%p ",
|
i = sprintf(buf, "TABLE: %s.%s %s To_Tdb=%p ",
|
||||||
SVP(tp->Creator), tp->Name, SVP(tp->Correl), tp->To_Tdb);
|
SVP(tp->Creator), tp->Name, SVP(tp->Srcdef), tp->To_Tdb);
|
||||||
strncat(ps, buf, n);
|
strncat(ps, buf, n);
|
||||||
n -= i;
|
n -= i;
|
||||||
} // endif tp
|
} // endif tp
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*************** TabCol H Declares Source Code File (.H) ***************/
|
/*************** TabCol H Declares Source Code File (.H) ***************/
|
||||||
/* Name: TABCOL.H Version 2.7 */
|
/* Name: TABCOL.H Version 2.8 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 1998-2012 */
|
/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */
|
||||||
/* */
|
/* */
|
||||||
/* This file contains the XTAB, COLUMN and XORDER class definitions. */
|
/* This file contains the XTAB, COLUMN and XORDER class definitions. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -15,23 +15,23 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Definition of class XTAB with all its method functions. */
|
/* Definition of class XTAB with all its method functions. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class DllExport XTAB: public BLOCK { // Table Name-Owner-Correl block.
|
class DllExport XTAB: public BLOCK { // Table Name-Owner-Srcdef block.
|
||||||
friend class TDBPRX;
|
friend class TDBPRX;
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
XTAB(LPCSTR name, LPCSTR correl = NULL);
|
XTAB(LPCSTR name, LPCSTR srcdef = NULL);
|
||||||
XTAB(PTABLE tp);
|
XTAB(PTABLE tp);
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
PTABLE GetNext(void) {return Next;}
|
PTABLE GetNext(void) {return Next;}
|
||||||
PTDB GetTo_Tdb(void) {return To_Tdb;}
|
PTDB GetTo_Tdb(void) {return To_Tdb;}
|
||||||
LPCSTR GetName(void) {return Name;}
|
LPCSTR GetName(void) {return Name;}
|
||||||
LPCSTR GetCorrel(void) {return Correl;}
|
LPCSTR GetSrc(void) {return Srcdef;}
|
||||||
LPCSTR GetCreator(void) {return Creator;}
|
LPCSTR GetCreator(void) {return Creator;}
|
||||||
LPCSTR GetQualifier(void) {return Qualifier;}
|
LPCSTR GetQualifier(void) {return Qualifier;}
|
||||||
void SetTo_Tdb(PTDB tdbp) {To_Tdb = tdbp;}
|
void SetTo_Tdb(PTDB tdbp) {To_Tdb = tdbp;}
|
||||||
void SetName(LPCSTR name) {Name = name;}
|
void SetName(LPCSTR name) {Name = name;}
|
||||||
void SetCorrel(LPCSTR correl) {Correl = correl;}
|
void SetSrc(LPCSTR srcdef) {Srcdef = srcdef;}
|
||||||
void SetCreator(LPCSTR crname) {Creator = crname;}
|
void SetCreator(LPCSTR crname) {Creator = crname;}
|
||||||
void SetQualifier(LPCSTR qname) {Qualifier = qname;}
|
void SetQualifier(LPCSTR qname) {Qualifier = qname;}
|
||||||
|
|
||||||
@@ -44,8 +44,8 @@ class DllExport XTAB: public BLOCK { // Table Name-Owner-Correl block.
|
|||||||
// Members
|
// Members
|
||||||
PTABLE Next; // Points to next table in chain
|
PTABLE Next; // Points to next table in chain
|
||||||
PTDB To_Tdb; // Points to Table description Block
|
PTDB To_Tdb; // Points to Table description Block
|
||||||
LPCSTR Name; // Table name (can be changed by LNA and PLG)
|
LPCSTR Name; // Table name
|
||||||
LPCSTR Correl; // Correlation name
|
LPCSTR Srcdef; // Table Source definition
|
||||||
LPCSTR Creator; // Creator name
|
LPCSTR Creator; // Creator name
|
||||||
LPCSTR Qualifier; // Qualifier name
|
LPCSTR Qualifier; // Qualifier name
|
||||||
}; // end of class XTAB
|
}; // end of class XTAB
|
||||||
|
@@ -1088,7 +1088,12 @@ bool TDBFMT::OpenDB(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
Linenum = 0;
|
Linenum = 0;
|
||||||
|
|
||||||
if (Use != USE_OPEN && (Columns || Mode == MODE_UPDATE)) {
|
if (Mode == MODE_INSERT || Mode == MODE_UPDATE) {
|
||||||
|
sprintf(g->Message, MSG(FMT_WRITE_NIY), "FMT");
|
||||||
|
return true; // NIY
|
||||||
|
} // endif Mode
|
||||||
|
|
||||||
|
if (Use != USE_OPEN && Columns) {
|
||||||
// Make the formats used to read records
|
// Make the formats used to read records
|
||||||
PSZ pfm;
|
PSZ pfm;
|
||||||
int i, n;
|
int i, n;
|
||||||
@@ -1096,17 +1101,12 @@ bool TDBFMT::OpenDB(PGLOBAL g)
|
|||||||
PCOLDEF cdp;
|
PCOLDEF cdp;
|
||||||
PDOSDEF tdp = (PDOSDEF)To_Def;
|
PDOSDEF tdp = (PDOSDEF)To_Def;
|
||||||
|
|
||||||
// if (Mode != MODE_UPDATE) {
|
for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
|
||||||
for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
|
if (!colp->IsSpecial()) // Not a pseudo column
|
||||||
if (!colp->IsSpecial()) // Not a pseudo column
|
Fields = max(Fields, (int)colp->Fldnum);
|
||||||
Fields = max(Fields, (int)colp->Fldnum);
|
|
||||||
|
|
||||||
if (Columns)
|
if (Columns)
|
||||||
Fields++; // Fldnum was 0 based
|
Fields++; // Fldnum was 0 based
|
||||||
|
|
||||||
// } else
|
|
||||||
// for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
|
|
||||||
// Fields++;
|
|
||||||
|
|
||||||
To_Fld = PlugSubAlloc(g, NULL, Lrecl + 1);
|
To_Fld = PlugSubAlloc(g, NULL, Lrecl + 1);
|
||||||
FldFormat = (PSZ*)PlugSubAlloc(g, NULL, sizeof(PSZ) * Fields);
|
FldFormat = (PSZ*)PlugSubAlloc(g, NULL, sizeof(PSZ) * Fields);
|
||||||
|
@@ -79,9 +79,11 @@ MYSQLDEF::MYSQLDEF(void)
|
|||||||
Hostname = NULL;
|
Hostname = NULL;
|
||||||
Database = NULL;
|
Database = NULL;
|
||||||
Tabname = NULL;
|
Tabname = NULL;
|
||||||
|
Srcdef = NULL;
|
||||||
Username = NULL;
|
Username = NULL;
|
||||||
Password = NULL;
|
Password = NULL;
|
||||||
Portnumber = 0;
|
Portnumber = 0;
|
||||||
|
Isview = FALSE;
|
||||||
Bind = FALSE;
|
Bind = FALSE;
|
||||||
Delayed = FALSE;
|
Delayed = FALSE;
|
||||||
} // end of MYSQLDEF constructor
|
} // end of MYSQLDEF constructor
|
||||||
@@ -302,8 +304,8 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
} else {
|
} else {
|
||||||
// MYSQL access from a PROXY table, not using URL
|
// MYSQL access from a PROXY table, not using URL
|
||||||
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
||||||
Tabname = Cat->GetStringCatInfo(g, "Name", Name); // Deprecated
|
Tabname = Name;
|
||||||
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
Isview = Cat->GetBoolCatInfo("View", FALSE);
|
||||||
|
|
||||||
// We must get connection parms from the calling table
|
// We must get connection parms from the calling table
|
||||||
Remove_tshp(Cat);
|
Remove_tshp(Cat);
|
||||||
@@ -313,6 +315,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
|
Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
|
||||||
} // endif am
|
} // endif am
|
||||||
|
|
||||||
|
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
||||||
|
Isview = TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of DefineAM
|
} // end of DefineAM
|
||||||
|
|
||||||
@@ -339,18 +344,22 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
|||||||
Host = tdp->GetHostname();
|
Host = tdp->GetHostname();
|
||||||
Database = tdp->GetDatabase();
|
Database = tdp->GetDatabase();
|
||||||
Tabname = tdp->GetTabname();
|
Tabname = tdp->GetTabname();
|
||||||
|
Srcdef = tdp->GetSrcdef();
|
||||||
User = tdp->GetUsername();
|
User = tdp->GetUsername();
|
||||||
Pwd = tdp->GetPassword();
|
Pwd = tdp->GetPassword();
|
||||||
Port = tdp->GetPortnumber();
|
Port = tdp->GetPortnumber();
|
||||||
|
Isview = tdp->Isview;
|
||||||
Prep = tdp->Bind;
|
Prep = tdp->Bind;
|
||||||
Delayed = tdp->Delayed;
|
Delayed = tdp->Delayed;
|
||||||
} else {
|
} else {
|
||||||
Host = NULL;
|
Host = NULL;
|
||||||
Database = NULL;
|
Database = NULL;
|
||||||
Tabname = NULL;
|
Tabname = NULL;
|
||||||
|
Srcdef = NULL;
|
||||||
User = NULL;
|
User = NULL;
|
||||||
Pwd = NULL;
|
Pwd = NULL;
|
||||||
Port = 0;
|
Port = 0;
|
||||||
|
Isview = FALSE;
|
||||||
Prep = FALSE;
|
Prep = FALSE;
|
||||||
Delayed = FALSE;
|
Delayed = FALSE;
|
||||||
} // endif tdp
|
} // endif tdp
|
||||||
@@ -370,9 +379,11 @@ TDBMYSQL::TDBMYSQL(PGLOBAL g, PTDBMY tdbp) : TDBASE(tdbp)
|
|||||||
Host = tdbp->Host;
|
Host = tdbp->Host;
|
||||||
Database = tdbp->Database;
|
Database = tdbp->Database;
|
||||||
Tabname = tdbp->Tabname;
|
Tabname = tdbp->Tabname;
|
||||||
|
Srcdef = tdbp->Srcdef;
|
||||||
User = tdbp->User;
|
User = tdbp->User;
|
||||||
Pwd = tdbp->Pwd;
|
Pwd = tdbp->Pwd;
|
||||||
Port = tdbp->Port;
|
Port = tdbp->Port;
|
||||||
|
Isview = tdbp->Isview;
|
||||||
Prep = tdbp->Prep;
|
Prep = tdbp->Prep;
|
||||||
Delayed = tdbp->Delayed;
|
Delayed = tdbp->Delayed;
|
||||||
Bind = NULL;
|
Bind = NULL;
|
||||||
@@ -418,55 +429,54 @@ PCOL TDBMYSQL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBMYSQL::MakeSelect(PGLOBAL g)
|
bool TDBMYSQL::MakeSelect(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *colist;
|
|
||||||
char *tk = "`";
|
char *tk = "`";
|
||||||
int len = 0, ncol = 0, rank = 0;
|
int rank = 0;
|
||||||
bool b = FALSE;
|
bool b = FALSE;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
PDBUSER dup = PlgGetUser(g);
|
//PDBUSER dup = PlgGetUser(g);
|
||||||
|
|
||||||
if (Query)
|
if (Query)
|
||||||
return FALSE; // already done
|
return FALSE; // already done
|
||||||
|
|
||||||
for (colp = Columns; colp; colp = colp->GetNext())
|
if (Srcdef) {
|
||||||
ncol++;
|
Query = Srcdef;
|
||||||
|
return false;
|
||||||
|
} // endif Srcdef
|
||||||
|
|
||||||
if (ncol) {
|
//Find the address of the suballocated query
|
||||||
colist = (char*)PlugSubAlloc(g, NULL, (NAM_LEN + 4) * ncol);
|
Query = (char*)PlugSubAlloc(g, NULL, 0);
|
||||||
*colist = '\0';
|
strcpy(Query, "SELECT ");
|
||||||
|
|
||||||
|
if (Columns) {
|
||||||
for (colp = Columns; colp; colp = colp->GetNext())
|
for (colp = Columns; colp; colp = colp->GetNext())
|
||||||
if (colp->IsSpecial()) {
|
if (colp->IsSpecial()) {
|
||||||
strcpy(g->Message, MSG(NO_SPEC_COL));
|
strcpy(g->Message, MSG(NO_SPEC_COL));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else {
|
} else {
|
||||||
if (b)
|
if (b)
|
||||||
strcat(colist, ", ");
|
strcat(Query, ", ");
|
||||||
else
|
else
|
||||||
b = TRUE;
|
b = TRUE;
|
||||||
|
|
||||||
strcat(strcat(strcat(colist, tk), colp->GetName()), tk);
|
strcat(strcat(strcat(Query, tk), colp->GetName()), tk);
|
||||||
((PMYCOL)colp)->Rank = rank++;
|
((PMYCOL)colp)->Rank = rank++;
|
||||||
} // endif colp
|
} // endif colp
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// ncol == 0 can occur for queries such as Query count(*) from...
|
// ncol == 0 can occur for views or queries such as
|
||||||
// for which we will count the rows from Query '*' from...
|
// Query count(*) from... for which we will count the rows from
|
||||||
|
// Query '*' from...
|
||||||
// (the use of a char constant minimize the result storage)
|
// (the use of a char constant minimize the result storage)
|
||||||
colist = (char*)PlugSubAlloc(g, NULL, 2);
|
strcat(Query, (Isview) ? "*" : "'*'");
|
||||||
strcpy(colist, "'*'");
|
|
||||||
} // endif ncol
|
} // endif ncol
|
||||||
|
|
||||||
// Below 32 is space to contain extra stuff
|
|
||||||
len += (strlen(colist) + strlen(Tabname) + 32);
|
|
||||||
len += (To_Filter ? strlen(To_Filter) + 7 : 0);
|
|
||||||
Query = (char*)PlugSubAlloc(g, NULL, len);
|
|
||||||
strcat(strcpy(Query, "SELECT "), colist);
|
|
||||||
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
|
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
|
||||||
|
|
||||||
if (To_Filter)
|
if (To_Filter)
|
||||||
strcat(strcat(Query, " WHERE "), To_Filter);
|
strcat(strcat(Query, " WHERE "), To_Filter);
|
||||||
|
|
||||||
|
// Now we know how much to suballocate
|
||||||
|
PlugSubAlloc(g, NULL, strlen(Query) + 1);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of MakeSelect
|
} // end of MakeSelect
|
||||||
|
|
||||||
@@ -751,7 +761,7 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
/* Table already open, just replace it at its beginning. */
|
/* Table already open, just replace it at its beginning. */
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
Myc.Rewind();
|
Myc.Rewind();
|
||||||
return FALSE;
|
return false;
|
||||||
} // endif use
|
} // endif use
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
@@ -763,7 +773,7 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (!Myc.Connected()) {
|
if (!Myc.Connected()) {
|
||||||
if (Myc.Open(g, Host, Database, User, Pwd, Port))
|
if (Myc.Open(g, Host, Database, User, Pwd, Port))
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
} // endif Connected
|
} // endif Connected
|
||||||
|
|
||||||
@@ -774,7 +784,24 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
if (!MakeSelect(g))
|
if (!MakeSelect(g))
|
||||||
m_Rc = Myc.ExecSQL(g, Query);
|
m_Rc = Myc.ExecSQL(g, Query);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (!Myc.m_Res || !Myc.m_Fields) {
|
||||||
|
sprintf(g->Message, "%s result", (Myc.m_Res) ? "Void" : "No");
|
||||||
|
Myc.Close();
|
||||||
|
return true;
|
||||||
|
} // endif m_Res
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
if (Srcdef)
|
||||||
|
if (SetColumnRanks(g))
|
||||||
|
return true;
|
||||||
|
|
||||||
} else if (Mode == MODE_INSERT) {
|
} else if (Mode == MODE_INSERT) {
|
||||||
|
if (Srcdef) {
|
||||||
|
strcpy(g->Message, "No insert into anonym views");
|
||||||
|
return true;
|
||||||
|
} // endif Srcdef
|
||||||
|
|
||||||
if (!MakeInsert(g)) {
|
if (!MakeInsert(g)) {
|
||||||
#if defined(MYSQL_PREPARED_STATEMENTS)
|
#if defined(MYSQL_PREPARED_STATEMENTS)
|
||||||
int n = (Prep) ? Myc.PrepareSQL(g, Query) : Nparm;
|
int n = (Prep) ? Myc.PrepareSQL(g, Query) : Nparm;
|
||||||
@@ -826,6 +853,55 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Set the rank of columns in the result set. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TDBMYSQL::SetColumnRanks(PGLOBAL g)
|
||||||
|
{
|
||||||
|
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
||||||
|
if (((PMYCOL)colp)->FindRank(g))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
} // end of SetColumnRanks
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Called by Parent table to make the columns of a View. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PCOL TDBMYSQL::MakeFieldColumn(PGLOBAL g, char *name)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
MYSQL_FIELD *fld;
|
||||||
|
PCOL cp, colp = NULL;
|
||||||
|
|
||||||
|
for (n = 0; n < Myc.m_Fields; n++) {
|
||||||
|
fld = &Myc.m_Res->fields[n];
|
||||||
|
|
||||||
|
if (!stricmp(name, fld->name)) {
|
||||||
|
colp = new(g) MYSQLCOL(fld, this, n);
|
||||||
|
|
||||||
|
if (colp->InitValue(g))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!Columns)
|
||||||
|
Columns = colp;
|
||||||
|
else for (cp = Columns; cp; cp = cp->GetNext())
|
||||||
|
if (!cp->GetNext()) {
|
||||||
|
cp->SetNext(colp);
|
||||||
|
break;
|
||||||
|
} // endif Next
|
||||||
|
|
||||||
|
break;
|
||||||
|
} // endif name
|
||||||
|
|
||||||
|
} // endfor n
|
||||||
|
|
||||||
|
if (!colp)
|
||||||
|
sprintf(g->Message, "Column %s is not in view", name);
|
||||||
|
|
||||||
|
return colp;
|
||||||
|
} // end of MakeFieldColumn
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Data Base read routine for MYSQL access method. */
|
/* Data Base read routine for MYSQL access method. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -939,7 +1015,7 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
|||||||
tdbp->SetColumns(this);
|
tdbp->SetColumns(this);
|
||||||
} // endif cprec
|
} // endif cprec
|
||||||
|
|
||||||
// Set additional Dos access method information for column.
|
// Set additional MySQL access method information for column.
|
||||||
Long = cdp->GetLong();
|
Long = cdp->GetLong();
|
||||||
Bind = NULL;
|
Bind = NULL;
|
||||||
To_Val = NULL;
|
To_Val = NULL;
|
||||||
@@ -951,6 +1027,33 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
|||||||
|
|
||||||
} // end of MYSQLCOL constructor
|
} // end of MYSQLCOL constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* MYSQLCOL public constructor. */
|
||||||
|
/***********************************************************************/
|
||||||
|
MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
|
||||||
|
: COLBLK(NULL, tdbp, i)
|
||||||
|
{
|
||||||
|
Name = fld->name;
|
||||||
|
Opt = 0;
|
||||||
|
Long = fld->length;
|
||||||
|
Buf_Type = MYSQLtoPLG(fld->type);
|
||||||
|
strcpy(Format.Type, GetFormatType(Buf_Type));
|
||||||
|
Format.Length = Long;
|
||||||
|
Format.Prec = fld->decimals;
|
||||||
|
ColUse = U_P;
|
||||||
|
Nullable = !IS_NOT_NULL(fld->flags);
|
||||||
|
|
||||||
|
// Set additional MySQL access method information for column.
|
||||||
|
Bind = NULL;
|
||||||
|
To_Val = NULL;
|
||||||
|
Slen = 0;
|
||||||
|
Rank = i;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
|
||||||
|
|
||||||
|
} // end of MYSQLCOL constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* MYSQLCOL constructor used for copying columns. */
|
/* MYSQLCOL constructor used for copying columns. */
|
||||||
/* tdbp is the pointer to the new table descriptor. */
|
/* tdbp is the pointer to the new table descriptor. */
|
||||||
@@ -964,6 +1067,24 @@ MYSQLCOL::MYSQLCOL(MYSQLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
|
|||||||
Rank = col1->Rank;
|
Rank = col1->Rank;
|
||||||
} // end of MYSQLCOL copy constructor
|
} // end of MYSQLCOL copy constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* FindRank: Find the rank of this column in the result set. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool MYSQLCOL::FindRank(PGLOBAL g)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
MYSQLC myc = ((PTDBMY)To_Tdb)->Myc;
|
||||||
|
|
||||||
|
for (n = 0; n < myc.m_Fields; n++)
|
||||||
|
if (!stricmp(Name, myc.m_Res->fields[n].name)) {
|
||||||
|
Rank = n;
|
||||||
|
return false;
|
||||||
|
} // endif Name
|
||||||
|
|
||||||
|
sprintf(g->Message, "Column %s not in result set", Name);
|
||||||
|
return true;
|
||||||
|
} // end of FindRank
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* SetBuffer: prepare a column block for write operation. */
|
/* SetBuffer: prepare a column block for write operation. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1049,11 +1170,6 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
|
|||||||
int rc;
|
int rc;
|
||||||
PTDBMY tdbp = (PTDBMY)To_Tdb;
|
PTDBMY tdbp = (PTDBMY)To_Tdb;
|
||||||
|
|
||||||
if (trace)
|
|
||||||
htrc("MySQL ReadColumn: name=%s\n", Name);
|
|
||||||
|
|
||||||
assert (Rank >= 0);
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* If physical fetching of the line was deferred, do it now. */
|
/* If physical fetching of the line was deferred, do it now. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
@@ -1066,14 +1182,17 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
|
|||||||
} else
|
} else
|
||||||
tdbp->Fetched = TRUE;
|
tdbp->Fetched = TRUE;
|
||||||
|
|
||||||
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank)))
|
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
|
||||||
|
if (trace)
|
||||||
|
htrc("MySQL ReadColumn: name=%s buf=%s\n", Name, buf);
|
||||||
|
|
||||||
Value->SetValue_char(buf, Long);
|
Value->SetValue_char(buf, Long);
|
||||||
else {
|
} else {
|
||||||
if (Nullable)
|
if (Nullable)
|
||||||
Value->SetNull(true);
|
Value->SetNull(true);
|
||||||
|
|
||||||
Value->Reset(); // Null value
|
Value->Reset(); // Null value
|
||||||
} // endelse
|
} // endif buf
|
||||||
|
|
||||||
} // end of ReadColumn
|
} // end of ReadColumn
|
||||||
|
|
||||||
@@ -1121,5 +1240,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PQRYRES TDBMCL::GetResult(PGLOBAL g)
|
PQRYRES TDBMCL::GetResult(PGLOBAL g)
|
||||||
{
|
{
|
||||||
return MyColumns(g, Host, Db, User, Pwd, Tab, NULL, Port, false, false);
|
return MyColumns(g, Host, Db, User, Pwd, Tab, NULL, Port, false);
|
||||||
} // end of GetResult
|
} // end of GetResult
|
||||||
|
@@ -30,6 +30,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
inline PSZ GetHostname(void) {return Hostname;};
|
inline PSZ GetHostname(void) {return Hostname;};
|
||||||
inline PSZ GetDatabase(void) {return Database;};
|
inline PSZ GetDatabase(void) {return Database;};
|
||||||
inline PSZ GetTabname(void) {return Tabname;}
|
inline PSZ GetTabname(void) {return Tabname;}
|
||||||
|
inline PSZ GetSrcdef(void) {return Srcdef;}
|
||||||
inline PSZ GetUsername(void) {return Username;};
|
inline PSZ GetUsername(void) {return Username;};
|
||||||
inline PSZ GetPassword(void) {return Password;};
|
inline PSZ GetPassword(void) {return Password;};
|
||||||
inline int GetPortnumber(void) {return Portnumber;}
|
inline int GetPortnumber(void) {return Portnumber;}
|
||||||
@@ -44,9 +45,11 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
PSZ Hostname; /* Host machine to use */
|
PSZ Hostname; /* Host machine to use */
|
||||||
PSZ Database; /* Database to be used by server */
|
PSZ Database; /* Database to be used by server */
|
||||||
PSZ Tabname; /* External table name */
|
PSZ Tabname; /* External table name */
|
||||||
|
PSZ Srcdef; /* The source table SQL definition */
|
||||||
PSZ Username; /* User logon name */
|
PSZ Username; /* User logon name */
|
||||||
PSZ Password; /* Password logon info */
|
PSZ Password; /* Password logon info */
|
||||||
int Portnumber; /* MySQL port number (0 = default) */
|
int Portnumber; /* MySQL port number (0 = default) */
|
||||||
|
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 */
|
||||||
}; // end of MYSQLDEF
|
}; // end of MYSQLDEF
|
||||||
@@ -72,6 +75,7 @@ class TDBMYSQL : public TDBASE {
|
|||||||
virtual int GetProgMax(PGLOBAL g);
|
virtual int GetProgMax(PGLOBAL g);
|
||||||
virtual void ResetDB(void) {N = 0;}
|
virtual void ResetDB(void) {N = 0;}
|
||||||
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
||||||
|
virtual bool IsView(void) {return Isview;}
|
||||||
void SetDatabase(LPCSTR db) {Database = (char*)db;}
|
void SetDatabase(LPCSTR db) {Database = (char*)db;}
|
||||||
|
|
||||||
// Database routines
|
// Database routines
|
||||||
@@ -83,6 +87,10 @@ class TDBMYSQL : public TDBASE {
|
|||||||
virtual int DeleteDB(PGLOBAL g, int irc);
|
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||||
virtual void CloseDB(PGLOBAL g);
|
virtual void CloseDB(PGLOBAL g);
|
||||||
|
|
||||||
|
// Specific routines
|
||||||
|
bool SetColumnRanks(PGLOBAL g);
|
||||||
|
PCOL MakeFieldColumn(PGLOBAL g, char *name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal functions
|
// Internal functions
|
||||||
bool MakeSelect(PGLOBAL g);
|
bool MakeSelect(PGLOBAL g);
|
||||||
@@ -99,9 +107,11 @@ class TDBMYSQL : public TDBASE {
|
|||||||
char *Pwd; // Password logon info
|
char *Pwd; // Password logon info
|
||||||
char *Database; // Database to be used by server
|
char *Database; // Database to be used by server
|
||||||
char *Tabname; // External table name
|
char *Tabname; // External table name
|
||||||
|
char *Srcdef; // The source table SQL definition
|
||||||
char *Query; // Points to SQL query
|
char *Query; // Points to SQL query
|
||||||
char *Qbuf; // Used for not prepared insert
|
char *Qbuf; // Used for not prepared insert
|
||||||
bool Fetched; // True when fetch was done
|
bool Fetched; // True when fetch was done
|
||||||
|
bool Isview; // True if this table is a MySQL view
|
||||||
bool Prep; // Use prepared statement on insert
|
bool Prep; // Use prepared statement on insert
|
||||||
bool Delayed; // Use delayed insert
|
bool Delayed; // Use delayed insert
|
||||||
int m_Rc; // Return code from command
|
int m_Rc; // Return code from command
|
||||||
@@ -119,6 +129,7 @@ class MYSQLCOL : public COLBLK {
|
|||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "MYSQL");
|
MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "MYSQL");
|
||||||
|
MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am = "MYSQL");
|
||||||
MYSQLCOL(MYSQLCOL *colp, PTDB tdbp); // Constructor used in copy process
|
MYSQLCOL(MYSQLCOL *colp, PTDB tdbp); // Constructor used in copy process
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
@@ -129,6 +140,7 @@ class MYSQLCOL : public COLBLK {
|
|||||||
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
|
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
|
||||||
virtual void ReadColumn(PGLOBAL g);
|
virtual void ReadColumn(PGLOBAL g);
|
||||||
virtual void WriteColumn(PGLOBAL g);
|
virtual void WriteColumn(PGLOBAL g);
|
||||||
|
bool FindRank(PGLOBAL g);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Default constructor not to be used
|
// Default constructor not to be used
|
||||||
|
@@ -85,19 +85,43 @@ PTDB OCCURDEF::GetTable(PGLOBAL g, MODE m)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp)
|
TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp)
|
||||||
{
|
{
|
||||||
//Tdbp = NULL; // Source table
|
//Tdbp = NULL; // Source table (in TDBPRX)
|
||||||
Tabname = tdp->Tablep->GetName(); // Name of source table
|
Tabname = tdp->Tablep->GetName(); // Name of source table
|
||||||
Colist = tdp->Colist; // List of source columns
|
Colist = tdp->Colist; // List of source columns
|
||||||
Xcolumn = tdp->Xcol; // Occur column name
|
Xcolumn = tdp->Xcol; // Occur column name
|
||||||
Rcolumn = tdp->Rcol; // Rank column name
|
Rcolumn = tdp->Rcol; // Rank column name
|
||||||
Xcolp = NULL; // To the OCCURCOL column
|
Xcolp = NULL; // To the OCCURCOL column
|
||||||
Col = NULL; // To source column blocks array
|
Col = NULL; // To source column blocks array
|
||||||
Mult = -1; // Multiplication factor
|
Mult = PrepareColist(); // Multiplication factor
|
||||||
N = 0; // The current table index
|
N = 0; // The current table index
|
||||||
M = 0; // The occurence rank
|
M = 0; // The occurence rank
|
||||||
RowFlag = 0; // 0: Ok, 1: Same, 2: Skip
|
RowFlag = 0; // 0: Ok, 1: Same, 2: Skip
|
||||||
} // end of TDBOCCUR constructor
|
} // end of TDBOCCUR constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Prepare and count columns in the column list. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBOCCUR::PrepareColist(void)
|
||||||
|
{
|
||||||
|
char *p, *pn;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
// Count the number of columns and change separator into null char
|
||||||
|
for (pn = Colist; ; pn += (strlen(pn) + 1))
|
||||||
|
// Separator can be ; if colist was specified in the option_list
|
||||||
|
if ((p = strchr(pn, ',')) || (p = strchr(pn, ';'))) {
|
||||||
|
*p++ = '\0';
|
||||||
|
n++;
|
||||||
|
} else {
|
||||||
|
if (*pn)
|
||||||
|
n++;
|
||||||
|
|
||||||
|
break;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
|
return n;
|
||||||
|
} // end of PrepareColist
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Allocate OCCUR/SRC column description block. */
|
/* Allocate OCCUR/SRC column description block. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -111,14 +135,8 @@ PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
|||||||
} else if (!stricmp(cdp->GetName(), Xcolumn)) {
|
} else if (!stricmp(cdp->GetName(), Xcolumn)) {
|
||||||
// Allocate the OCCUR column
|
// Allocate the OCCUR column
|
||||||
colp = Xcolp = new(g) OCCURCOL(cdp, this, n);
|
colp = Xcolp = new(g) OCCURCOL(cdp, this, n);
|
||||||
} else {
|
} else
|
||||||
colp = new(g) PRXCOL(cdp, this, cprec, n);
|
return new(g) PRXCOL(cdp, this, cprec, n);
|
||||||
|
|
||||||
if (((PPRXCOL)colp)->Init(g))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return colp;
|
|
||||||
} //endif name
|
|
||||||
|
|
||||||
if (cprec) {
|
if (cprec) {
|
||||||
colp->SetNext(cprec->GetNext());
|
colp->SetNext(cprec->GetNext());
|
||||||
@@ -136,75 +154,100 @@ PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBOCCUR::InitTable(PGLOBAL g)
|
bool TDBOCCUR::InitTable(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (!Tdbp) {
|
if (!Tdbp)
|
||||||
// Get the table description block of this table
|
// Get the table description block of this table
|
||||||
if (!(Tdbp = (PTDBASE)GetSubTable(g, ((POCCURDEF)To_Def)->Tablep)))
|
if (!(Tdbp = GetSubTable(g, ((POCCURDEF)To_Def)->Tablep, TRUE)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (MakeColumnList(g) < 0)
|
if (!Tdbp->IsView())
|
||||||
|
if (MakeColumnList(g))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
} // endif Tdbp
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of InitTable
|
} // end of InitTable
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Allocate OCCUR column description block. */
|
/* Allocate OCCUR column description block. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBOCCUR::MakeColumnList(PGLOBAL g)
|
bool TDBOCCUR::MakeColumnList(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (Mult < 0) {
|
char *pn;
|
||||||
char *p, *pn;
|
int i;
|
||||||
int i;
|
PCOL colp;
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
// Count the number of columns and change separator into null char
|
for (colp = Columns; colp; colp = colp->GetNext())
|
||||||
for (pn = Colist; ; pn += (strlen(pn) + 1))
|
if (colp->GetAmType() == TYPE_AM_PRX)
|
||||||
if ((p = strchr(pn, ',')) || (p = strchr(pn, ';'))) {
|
if (((PPRXCOL)colp)->Init(g))
|
||||||
*p++ = '\0';
|
return true;
|
||||||
n++;
|
|
||||||
} else {
|
|
||||||
if (*pn)
|
|
||||||
n++;
|
|
||||||
|
|
||||||
break;
|
Col = (PCOL*)PlugSubAlloc(g, NULL, Mult * sizeof(PCOL));
|
||||||
} // endif p
|
|
||||||
|
|
||||||
Col = (PCOL*)PlugSubAlloc(g, NULL, n * sizeof(PCOL));
|
for (i = 0, pn = Colist; i < Mult; 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 true;
|
||||||
|
} // endif Col
|
||||||
|
|
||||||
for (i = 0, pn = Colist; i < n; i++, pn += (strlen(pn) + 1)) {
|
if (Col[i]->InitValue(g)) {
|
||||||
if (!(Col[i] = Tdbp->ColDB(g, pn, 0))) {
|
strcpy(g->Message, "OCCUR InitValue failed");
|
||||||
// Column not found in table
|
return true;
|
||||||
sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname);
|
} // endif InitValue
|
||||||
return -1;
|
|
||||||
} // endif Col
|
|
||||||
|
|
||||||
if (Col[i]->InitValue(g)) {
|
} // endfor i
|
||||||
strcpy(g->Message, "OCCUR InitValue failed");
|
|
||||||
return -1;
|
|
||||||
} // endif InitValue
|
|
||||||
|
|
||||||
} // endfor i
|
return false;
|
||||||
|
|
||||||
// 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
|
} // end of MakeColumnList
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Allocate OCCUR column description block for a view. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TDBOCCUR::ViewColumnList(PGLOBAL g)
|
||||||
|
{
|
||||||
|
char *pn;
|
||||||
|
int i;
|
||||||
|
PCOL colp, cp;
|
||||||
|
PTDBMY tdbp;
|
||||||
|
|
||||||
|
if (!Tdbp->IsView())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Tdbp->GetAmType() != TYPE_AM_MYSQL) {
|
||||||
|
strcpy(g->Message, "View is not MySQL");
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
tdbp = (PTDBMY)Tdbp;
|
||||||
|
|
||||||
|
for (cp = Columns; cp; cp = cp->GetNext())
|
||||||
|
if (cp->GetAmType() == TYPE_AM_PRX) {
|
||||||
|
if ((colp = tdbp->MakeFieldColumn(g, cp->GetName()))) {
|
||||||
|
((PPRXCOL)cp)->Colp = colp;
|
||||||
|
((PPRXCOL)cp)->To_Val = colp->GetValue();
|
||||||
|
} else
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} // endif Type
|
||||||
|
|
||||||
|
Col = (PCOL*)PlugSubAlloc(g, NULL, Mult * sizeof(PCOL));
|
||||||
|
|
||||||
|
for (i = 0, pn = Colist; i < Mult; i++, pn += (strlen(pn) + 1))
|
||||||
|
if (!(Col[i] = tdbp->MakeFieldColumn(g, pn))) {
|
||||||
|
// Column not found in table
|
||||||
|
sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname);
|
||||||
|
return true;
|
||||||
|
} // endif Col
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // end of ViewColumnList
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* OCCUR GetMaxSize: returns the maximum number of rows in the table. */
|
/* OCCUR GetMaxSize: returns the maximum number of rows in the table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBOCCUR::GetMaxSize(PGLOBAL g)
|
int TDBOCCUR::GetMaxSize(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (MaxSize < 0) {
|
if (MaxSize < 0) {
|
||||||
if (InitTable(g))
|
if (!(Tdbp = GetSubTable(g, ((POCCURDEF)To_Def)->Tablep, TRUE)))
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
MaxSize = Mult * Tdbp->GetMaxSize(g);
|
MaxSize = Mult * Tdbp->GetMaxSize(g);
|
||||||
} // endif MaxSize
|
} // endif MaxSize
|
||||||
@@ -252,7 +295,7 @@ bool TDBOCCUR::OpenDB(PGLOBAL g)
|
|||||||
/* Do it here if not done yet. */
|
/* Do it here if not done yet. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (InitTable(g))
|
if (InitTable(g))
|
||||||
return NULL;
|
return TRUE;
|
||||||
|
|
||||||
if (Xcolp)
|
if (Xcolp)
|
||||||
// Lock this column so it is evaluated by its table only
|
// Lock this column so it is evaluated by its table only
|
||||||
@@ -269,7 +312,10 @@ bool TDBOCCUR::OpenDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Do open the source table. */
|
/* Do open the source table. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
return Tdbp->OpenDB(g);
|
if (Tdbp->OpenDB(g))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return ViewColumnList(g);
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -52,21 +52,22 @@ class TDBOCCUR : public TDBPRX {
|
|||||||
TDBOCCUR(POCCURDEF tdp);
|
TDBOCCUR(POCCURDEF tdp);
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
virtual AMT GetAmType(void) {return TYPE_AM_OCCUR;}
|
virtual AMT GetAmType(void) {return TYPE_AM_OCCUR;}
|
||||||
void SetTdbp(PTDBASE tdbp) {Tdbp = tdbp;}
|
void SetTdbp(PTDBASE tdbp) {Tdbp = tdbp;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual void ResetDB(void) {N = 0; Tdbp->ResetDB();}
|
virtual void ResetDB(void) {N = 0; Tdbp->ResetDB();}
|
||||||
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
||||||
PTDB GetSourceTable(PGLOBAL g);
|
int PrepareColist(void);
|
||||||
int MakeColumnList(PGLOBAL g);
|
bool MakeColumnList(PGLOBAL g);
|
||||||
|
bool ViewColumnList(PGLOBAL g);
|
||||||
|
|
||||||
// Database routines
|
// Database routines
|
||||||
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
||||||
virtual bool InitTable(PGLOBAL g);
|
virtual bool InitTable(PGLOBAL g);
|
||||||
virtual int GetMaxSize(PGLOBAL g);
|
virtual int GetMaxSize(PGLOBAL g);
|
||||||
virtual bool OpenDB(PGLOBAL g);
|
virtual bool OpenDB(PGLOBAL g);
|
||||||
virtual int ReadDB(PGLOBAL g);
|
virtual int ReadDB(PGLOBAL g);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,14 @@
|
|||||||
/************** TabPivot H Declares Source Code File (.H) **************/
|
/************** TabPivot H Declares Source Code File (.H) **************/
|
||||||
/* Name: TABPIVOT.H Version 1.3 */
|
/* Name: TABPIVOT.H Version 1.4 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 2005-2012 */
|
/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
|
||||||
/* */
|
/* */
|
||||||
/* This file contains the PIVOT classes declares. */
|
/* This file contains the PIVOT classes declares. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
typedef class PIVOTDEF *PPIVOTDEF;
|
||||||
typedef class TDBPIVOT *PTDBPIVOT;
|
typedef class TDBPIVOT *PTDBPIVOT;
|
||||||
typedef class FNCCOL *PFNCCOL;
|
typedef class FNCCOL *PFNCCOL;
|
||||||
typedef class SRCCOL *PSRCCOL;
|
typedef class SRCCOL *PSRCCOL;
|
||||||
typedef class TDBQRS *PTDBQRS;
|
|
||||||
typedef class QRSCOL *PQRSCOL;
|
|
||||||
|
|
||||||
/* -------------------------- PIVOT classes -------------------------- */
|
/* -------------------------- PIVOT classes -------------------------- */
|
||||||
|
|
||||||
@@ -22,7 +21,6 @@ typedef class QRSCOL *PQRSCOL;
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* PIVOT table. */
|
/* PIVOT table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
//ass DllExport PIVOTDEF : public PRXDEF {/* Logical table description */
|
|
||||||
class PIVOTDEF : public PRXDEF { /* Logical table description */
|
class PIVOTDEF : public PRXDEF { /* Logical table description */
|
||||||
friend class TDBPIVOT;
|
friend class TDBPIVOT;
|
||||||
public:
|
public:
|
||||||
@@ -55,22 +53,16 @@ class PIVOTDEF : public PRXDEF { /* Logical table description */
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* This is the class declaration for the PIVOT table. */
|
/* This is the class declaration for the PIVOT table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
//ass DllExport TDBPIVOT : public TDBASE, public CSORT {
|
|
||||||
class TDBPIVOT : public TDBPRX {
|
class TDBPIVOT : public TDBPRX {
|
||||||
friend class FNCCOL;
|
friend class FNCCOL;
|
||||||
//friend class SRCCOL;
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TDBPIVOT(PPIVOTDEF tdp);
|
TDBPIVOT(PPIVOTDEF tdp);
|
||||||
//TDBPIVOT(PTDBPIVOT tdbp);
|
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
virtual AMT GetAmType(void) {return TYPE_AM_PIVOT;}
|
virtual AMT GetAmType(void) {return TYPE_AM_PIVOT;}
|
||||||
//virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBPIVOT(this);}
|
|
||||||
// void SetTdbp(PTDB tdbp) {Tdbp = tdbp;}
|
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
//virtual PTDB CopyOne(PTABS t);
|
|
||||||
virtual int GetRecpos(void) {return N;}
|
virtual int GetRecpos(void) {return N;}
|
||||||
virtual void ResetDB(void) {N = 0;}
|
virtual void ResetDB(void) {N = 0;}
|
||||||
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
||||||
@@ -84,22 +76,17 @@ class TDBPIVOT : public TDBPRX {
|
|||||||
virtual int DeleteDB(PGLOBAL g, int irc);
|
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||||
virtual void CloseDB(PGLOBAL g);
|
virtual void CloseDB(PGLOBAL g);
|
||||||
|
|
||||||
// The sorting function
|
|
||||||
//virtual int Qcompare(int *, int *);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool GetSourceTable(PGLOBAL g);
|
// Internal routines
|
||||||
//int MakePivotColumns(PGLOBAL g);
|
bool GetSourceTable(PGLOBAL g);
|
||||||
//bool UpdateTableFields(PGLOBAL g, int n);
|
bool MakePivotColumns(PGLOBAL g);
|
||||||
|
bool MakeViewColumns(PGLOBAL g);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
//MYSQLC Myc; // MySQL connection class
|
|
||||||
//PTDBQRS Tqrp; // To the source table result
|
|
||||||
char *Host; // Host machine to use
|
char *Host; // Host machine to use
|
||||||
char *User; // User logon info
|
char *User; // User logon info
|
||||||
char *Pwd; // Password logon info
|
char *Pwd; // Password logon info
|
||||||
char *Database; // Database to be used by server
|
char *Database; // Database to be used by server
|
||||||
//PQRYRES Qryp; // Points to Query result block
|
|
||||||
char *Tabname; // Name of source table
|
char *Tabname; // Name of source table
|
||||||
char *Tabsrc; // SQL of source table
|
char *Tabsrc; // SQL of source table
|
||||||
char *Picol; // Pivot column name
|
char *Picol; // Pivot column name
|
||||||
@@ -108,9 +95,6 @@ class TDBPIVOT : public TDBPRX {
|
|||||||
PCOL Fcolp; // To the function column in source
|
PCOL Fcolp; // To the function column in source
|
||||||
PCOL Xcolp; // To the pivot column in source
|
PCOL Xcolp; // To the pivot column in source
|
||||||
PCOL Dcolp; // To the dump column
|
PCOL Dcolp; // To the dump column
|
||||||
//PCOLRES Xresp; // To the pivot result column
|
|
||||||
//PCOLRES To_Sort; // Saved Qryp To_Sort pointer
|
|
||||||
//PVBLK Rblkp; // The value block of the pivot column
|
|
||||||
bool GBdone; // True when subtable is "Group by"
|
bool GBdone; // True when subtable is "Group by"
|
||||||
bool Accept; // TRUE if no match is accepted
|
bool Accept; // TRUE if no match is accepted
|
||||||
int Mult; // Multiplication factor
|
int Mult; // Multiplication factor
|
||||||
@@ -168,75 +152,4 @@ class SRCCOL : public PRXCOL {
|
|||||||
SRCCOL(void) {}
|
SRCCOL(void) {}
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
//PVAL Cnval;
|
|
||||||
}; // end of class SRCCOL
|
}; // end of class SRCCOL
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
/* TDBQRS: This is the Access Method class declaration for the Query */
|
|
||||||
/* Result stored in memory in the current work area (volatil). */
|
|
||||||
/***********************************************************************/
|
|
||||||
class DllExport TDBQRS : public TDBASE {
|
|
||||||
friend class QRSCOL;
|
|
||||||
public:
|
|
||||||
// Constructor
|
|
||||||
TDBQRS(PQRYRES qrp) : TDBASE() {Qrp = qrp; CurPos = 0;}
|
|
||||||
TDBQRS(PTDBQRS tdbp);
|
|
||||||
|
|
||||||
// Implementation
|
|
||||||
virtual AMT GetAmType(void) {return TYPE_AM_QRS;}
|
|
||||||
virtual PTDB Duplicate(PGLOBAL g)
|
|
||||||
{return (PTDB)new(g) TDBQRS(this);}
|
|
||||||
PQRYRES GetQrp(void) {return Qrp;}
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
virtual PTDB CopyOne(PTABS t);
|
|
||||||
virtual int RowNumber(PGLOBAL g, BOOL b = FALSE);
|
|
||||||
virtual int GetRecpos(void);
|
|
||||||
//virtual PCATLG GetCat(void);
|
|
||||||
//virtual PSZ GetPath(void);
|
|
||||||
virtual int GetBadLines(void) {return Qrp->BadLines;}
|
|
||||||
|
|
||||||
// Database routines
|
|
||||||
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
|
|
||||||
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);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TDBQRS(void) : TDBASE() {} // Standard constructor not to be used
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Members
|
|
||||||
PQRYRES Qrp; // Points to Query Result block
|
|
||||||
int CurPos; // Current line position
|
|
||||||
}; // end of class TDBQRS
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
/* Class QRSCOL: QRS access method column descriptor. */
|
|
||||||
/***********************************************************************/
|
|
||||||
class DllExport QRSCOL : public COLBLK {
|
|
||||||
friend class TDBQRS;
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
QRSCOL(PGLOBAL g, PCOLRES crp, PTDB tdbp, PCOL cprec, int i);
|
|
||||||
QRSCOL(QRSCOL *colp, PTDB tdbp); // Constructor used in copy process
|
|
||||||
|
|
||||||
// Implementation
|
|
||||||
virtual int GetAmType(void) {return TYPE_AM_QRS;}
|
|
||||||
PCOLRES GetCrp(void) {return Crp;}
|
|
||||||
void *GetQrsData(void) {return Crp->Kdata;}
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
virtual void ReadColumn(PGLOBAL g);
|
|
||||||
virtual void Print(PGLOBAL g, FILE *, uint);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QRSCOL(void) {} // Default constructor not to be used
|
|
||||||
|
|
||||||
// Members
|
|
||||||
PCOLRES Crp;
|
|
||||||
}; // end of class QRSCOL
|
|
||||||
|
|
||||||
|
@@ -216,7 +216,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
PTABLE tp, tabp;
|
PTABLE tp, tabp;
|
||||||
PTDB tdbp;
|
PTDBASE tdbp;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
PTBLDEF tdp = (PTBLDEF)To_Def;
|
PTBLDEF tdp = (PTBLDEF)To_Def;
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
n++;
|
n++;
|
||||||
} // endif filp
|
} // endif filp
|
||||||
|
|
||||||
} // endfor tblp
|
} // endfor tp
|
||||||
|
|
||||||
//NumTables = n;
|
//NumTables = n;
|
||||||
To_Filter = NULL; // To avoid doing it several times
|
To_Filter = NULL; // To avoid doing it several times
|
||||||
|
@@ -90,20 +90,21 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
|
|||||||
// 1 2 4 8
|
// 1 2 4 8
|
||||||
//flags = GTS_TABLE | GTS_VIEW | GTS_NOLOCK | GTS_FORCE_DISCOVERY;
|
//flags = GTS_TABLE | GTS_VIEW | GTS_NOLOCK | GTS_FORCE_DISCOVERY;
|
||||||
|
|
||||||
if (!open_table_def(thd, s, GTS_TABLE)) {
|
if (!open_table_def(thd, s, GTS_TABLE | GTS_VIEW)) {
|
||||||
#ifdef DBUG_OFF
|
if (!s->is_view) {
|
||||||
if (stricmp(s->db_plugin->name.str, "connect")) {
|
if (stricmp(plugin_name(s->db_plugin)->str, "connect")) {
|
||||||
#else
|
|
||||||
if (stricmp((*s->db_plugin)->name.str, "connect")) {
|
|
||||||
#endif
|
|
||||||
#if defined(MYSQL_SUPPORT)
|
#if defined(MYSQL_SUPPORT)
|
||||||
mysql = true;
|
mysql = true;
|
||||||
#else // !MYSQL_SUPPORT
|
#else // !MYSQL_SUPPORT
|
||||||
sprintf(g->Message, "%s.%s is not a CONNECT table", db, name);
|
sprintf(g->Message, "%s.%s is not a CONNECT table", db, name);
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif // MYSQL_SUPPORT
|
#endif // MYSQL_SUPPORT
|
||||||
} else
|
} else
|
||||||
mysql = false;
|
mysql = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
mysql = true;
|
||||||
|
} // endif is_view
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sprintf(g->Message, "Error %d opening share\n", s->error);
|
sprintf(g->Message, "Error %d opening share\n", s->error);
|
||||||
@@ -139,9 +140,12 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
|||||||
PCOLRES crp;
|
PCOLRES crp;
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
if (!(s = GetTableShare(g, thd, db, name, mysql)))
|
if (!(s = GetTableShare(g, thd, db, name, mysql))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
} else if (s->is_view) {
|
||||||
|
strcpy(g->Message, "Cannot retreive Proxy columns from a view");
|
||||||
|
return NULL;
|
||||||
|
} else
|
||||||
n = s->fieldnames.count;
|
n = s->fieldnames.count;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -257,23 +261,27 @@ PRXDEF::PRXDEF(void)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
{
|
{
|
||||||
char *pn, *db, *tab;
|
char *pn, *db, *tab, *def = NULL;
|
||||||
|
|
||||||
db = Cat->GetStringCatInfo(g, "Dbname", "*");
|
db = Cat->GetStringCatInfo(g, "Dbname", "*");
|
||||||
|
def = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
||||||
|
|
||||||
if (!(tab = Cat->GetStringCatInfo(g, "Tabname", NULL))) {
|
if (!(tab = Cat->GetStringCatInfo(g, "Tabname", NULL))) {
|
||||||
strcpy(g->Message, "Missing object table name");
|
if (!def) {
|
||||||
return TRUE;
|
strcpy(g->Message, "Missing object table definition");
|
||||||
} // endif tab
|
return TRUE;
|
||||||
|
} else
|
||||||
|
tab = "Noname";
|
||||||
|
|
||||||
// Analyze the table name, it may have the format: [dbname.]tabname
|
} else
|
||||||
if ((pn = strchr(tab, '.'))) {
|
// Analyze the table name, it may have the format: [dbname.]tabname
|
||||||
*pn++ = 0;
|
if ((pn = strchr(tab, '.'))) {
|
||||||
db = tab;
|
*pn++ = 0;
|
||||||
tab = pn;
|
db = tab;
|
||||||
} // endif pn
|
tab = pn;
|
||||||
|
} // endif pn
|
||||||
|
|
||||||
Tablep = new(g) XTAB(tab);
|
Tablep = new(g) XTAB(tab, def);
|
||||||
Tablep->SetQualifier(db);
|
Tablep->SetQualifier(db);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of DefineAM
|
} // end of DefineAM
|
||||||
@@ -303,12 +311,13 @@ TDBPRX::TDBPRX(PPRXDEF tdp) : TDBASE(tdp)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Get the PTDB of the sub-table. */
|
/* Get the PTDB of the sub-table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PTDB TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp)
|
PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
|
||||||
{
|
{
|
||||||
char *db, *name;
|
char *db, *name;
|
||||||
bool mysql;
|
bool mysql = true;
|
||||||
PTDB tdbp = NULL;
|
PTDB tdbp = NULL;
|
||||||
TABLE_SHARE *s;
|
TABLE_SHARE *s = NULL;
|
||||||
|
Field* *fp;
|
||||||
PCATLG cat = To_Def->GetCat();
|
PCATLG cat = To_Def->GetCat();
|
||||||
PHC hc = ((MYCAT*)cat)->GetHandler();
|
PHC hc = ((MYCAT*)cat)->GetHandler();
|
||||||
LPCSTR cdb, curdb = hc->GetDBName(NULL);
|
LPCSTR cdb, curdb = hc->GetDBName(NULL);
|
||||||
@@ -328,10 +337,20 @@ PTDB TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp)
|
|||||||
|
|
||||||
} // endfor tp
|
} // endfor tp
|
||||||
|
|
||||||
if (!(s = GetTableShare(g, thd, db, name, mysql)))
|
if (!tabp->GetSrc()) {
|
||||||
return NULL;
|
if (!(s = GetTableShare(g, thd, db, name, mysql)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
hc->tshp = s;
|
if (s->is_view && !b)
|
||||||
|
s->field = hc->get_table()->s->field;
|
||||||
|
|
||||||
|
hc->tshp = s;
|
||||||
|
} else if (b) {
|
||||||
|
// Don't use caller's columns
|
||||||
|
fp = hc->get_table()->field;
|
||||||
|
hc->get_table()->field = NULL;
|
||||||
|
hc->get_table()->s->option_struct->srcdef = tabp->GetSrc();
|
||||||
|
} // endif srcdef
|
||||||
|
|
||||||
if (mysql) {
|
if (mysql) {
|
||||||
#if defined(MYSQL_SUPPORT)
|
#if defined(MYSQL_SUPPORT)
|
||||||
@@ -355,15 +374,23 @@ PTDB TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp)
|
|||||||
tdbp = cat->GetTable(g, tabp);
|
tdbp = cat->GetTable(g, tabp);
|
||||||
} // endif mysql
|
} // endif mysql
|
||||||
|
|
||||||
hc->tshp = NULL;
|
if (s) {
|
||||||
|
if (s->is_view && !b)
|
||||||
|
s->field = NULL;
|
||||||
|
|
||||||
|
hc->tshp = NULL;
|
||||||
|
} else if (b)
|
||||||
|
hc->get_table()->field = fp;
|
||||||
|
|
||||||
if (trace && tdbp)
|
if (trace && tdbp)
|
||||||
htrc("Subtable %s in %s\n",
|
htrc("Subtable %s in %s\n",
|
||||||
name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
|
name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
|
||||||
|
|
||||||
err:
|
err:
|
||||||
free_table_share(s);
|
if (s)
|
||||||
return tdbp;
|
free_table_share(s);
|
||||||
|
|
||||||
|
return (PTDBASE)tdbp;
|
||||||
} // end of GetSubTable
|
} // end of GetSubTable
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -373,7 +400,7 @@ bool TDBPRX::InitTable(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
if (!Tdbp) {
|
if (!Tdbp) {
|
||||||
// Get the table description block of this table
|
// Get the table description block of this table
|
||||||
if (!(Tdbp = (PTDBASE)GetSubTable(g, ((PPRXDEF)To_Def)->Tablep)))
|
if (!(Tdbp = GetSubTable(g, ((PPRXDEF)To_Def)->Tablep)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
} // endif Tdbp
|
} // endif Tdbp
|
||||||
|
@@ -78,7 +78,7 @@ class DllExport TDBPRX : public TDBASE {
|
|||||||
virtual int WriteDB(PGLOBAL g);
|
virtual int WriteDB(PGLOBAL g);
|
||||||
virtual int DeleteDB(PGLOBAL g, int irc);
|
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||||
virtual void CloseDB(PGLOBAL g) {if (Tdbp) Tdbp->CloseDB(g);}
|
virtual void CloseDB(PGLOBAL g) {if (Tdbp) Tdbp->CloseDB(g);}
|
||||||
PTDB GetSubTable(PGLOBAL g, PTABLE tabp);
|
PTDBASE GetSubTable(PGLOBAL g, PTABLE tabp, bool b = false);
|
||||||
void RemoveNext(PTABLE tp);
|
void RemoveNext(PTABLE tp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -93,6 +93,7 @@ class DllExport TDBPRX : public TDBASE {
|
|||||||
class DllExport PRXCOL : public COLBLK {
|
class DllExport PRXCOL : public COLBLK {
|
||||||
friend class TDBPRX;
|
friend class TDBPRX;
|
||||||
friend class TDBTBL;
|
friend class TDBTBL;
|
||||||
|
friend class TDBOCCUR;
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "PRX");
|
PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "PRX");
|
||||||
|
@@ -173,6 +173,7 @@ class DllExport TDBASE : public TDB {
|
|||||||
virtual int GetRecpos(void) = 0;
|
virtual int GetRecpos(void) = 0;
|
||||||
virtual bool SetRecpos(PGLOBAL g, int recpos);
|
virtual bool SetRecpos(PGLOBAL g, int recpos);
|
||||||
virtual bool IsReadOnly(void) {return Read_Only;}
|
virtual bool IsReadOnly(void) {return Read_Only;}
|
||||||
|
virtual bool IsView(void) {return FALSE;}
|
||||||
virtual CHARSET_INFO *data_charset()
|
virtual CHARSET_INFO *data_charset()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user