mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
56948ee54c
clang15 finally errors on old prototype definations. Its also a lot fussier about variables that aren't used as is the case a number of time with loop counters that aren't examined. RocksDB was complaining that its get_range function was declared without the array length in ha_rocksdb.h. While a constant is used rather than trying to import the Rdb_key_def::INDEX_NUMBER_SIZE header (was causing a lot of errors on the defination of other orders). If the constant does change can be assured that the same compile warnings will tell us of the error. The ha_rocksdb::index_read_map_impl DBUG_EXECUTE_IF was similar to the existing endless functions used in replication tests. Its rather moot point as the rocksdb.force_shutdown test that uses myrocks_busy_loop_on_row_read is currently disabled.
874 lines
28 KiB
C++
874 lines
28 KiB
C++
/************* TabTbl C++ Program Source Code File (.CPP) **************/
|
|
/* PROGRAM NAME: TABTBL */
|
|
/* ------------- */
|
|
/* Version 1.9 */
|
|
/* */
|
|
/* Author: Olivier BERTRAND 2008-2018 */
|
|
/* */
|
|
/* WHAT THIS PROGRAM DOES: */
|
|
/* ----------------------- */
|
|
/* This program are the TDBTBL class DB routines. */
|
|
/* */
|
|
/* WHAT YOU NEED TO COMPILE THIS PROGRAM: */
|
|
/* -------------------------------------- */
|
|
/* */
|
|
/* REQUIRED FILES: */
|
|
/* --------------- */
|
|
/* TABTBL.CPP - Source code */
|
|
/* PLGDBSEM.H - DB application declaration file */
|
|
/* TABDOS.H - TABDOS classes declaration file */
|
|
/* TABTBL.H - TABTBL classes declaration file */
|
|
/* GLOBAL.H - Global declaration file */
|
|
/* */
|
|
/* REQUIRED LIBRARIES: */
|
|
/* ------------------- */
|
|
/* Large model C library */
|
|
/* */
|
|
/* REQUIRED PROGRAMS: */
|
|
/* ------------------ */
|
|
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
|
|
/* */
|
|
/***********************************************************************/
|
|
|
|
/***********************************************************************/
|
|
/* Include relevant section of system dependant header files. */
|
|
/***********************************************************************/
|
|
//#include "sql_base.h"
|
|
#include "my_global.h"
|
|
#include "table.h" // MySQL table definitions
|
|
#if defined(_WIN32)
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#if defined(__BORLANDC__)
|
|
#define __MFC_COMPAT__ // To define min/max as macro
|
|
#endif
|
|
//#include <windows.h>
|
|
#else
|
|
#if defined(UNIX)
|
|
#include <fnmatch.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "osutil.h"
|
|
#else
|
|
//#include <io.h>
|
|
#endif
|
|
//#include <fcntl.h>
|
|
#endif
|
|
|
|
/***********************************************************************/
|
|
/* Include application header files: */
|
|
/***********************************************************************/
|
|
#include "global.h" // global declarations
|
|
#include "plgdbsem.h" // DB application declarations
|
|
#include "reldef.h" // DB definition declares
|
|
#include "filamtxt.h"
|
|
#include "tabcol.h"
|
|
#include "tabdos.h" // TDBDOS and DOSCOL class dcls
|
|
#include "tabtbl.h"
|
|
#include "tabext.h"
|
|
#include "tabmysql.h"
|
|
#include "ha_connect.h"
|
|
|
|
#if defined(_WIN32)
|
|
#if defined(__BORLANDC__)
|
|
#define SYSEXIT void _USERENTRY
|
|
#else
|
|
#define SYSEXIT void
|
|
#endif
|
|
#else // !_WIN32
|
|
#define SYSEXIT void *
|
|
#endif // !_WIN32
|
|
|
|
extern pthread_mutex_t tblmut;
|
|
|
|
/* ---------------------------- Class TBLDEF ---------------------------- */
|
|
|
|
/**************************************************************************/
|
|
/* Constructor. */
|
|
/**************************************************************************/
|
|
TBLDEF::TBLDEF(void)
|
|
{
|
|
//To_Tables = NULL;
|
|
Accept = false;
|
|
Thread = false;
|
|
Maxerr = 0;
|
|
Ntables = 0;
|
|
Pseudo = 3;
|
|
} // end of TBLDEF constructor
|
|
|
|
/**************************************************************************/
|
|
/* DefineAM: define specific AM block values from XDB file. */
|
|
/**************************************************************************/
|
|
bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR, int)
|
|
{
|
|
char *tablist, *dbname, *def = NULL;
|
|
|
|
Desc = "Table list table";
|
|
tablist = GetStringCatInfo(g, "Tablist", "");
|
|
dbname = GetStringCatInfo(g, "Dbname", "*");
|
|
def = GetStringCatInfo(g, "Srcdef", NULL);
|
|
Ntables = 0;
|
|
|
|
if (*tablist) {
|
|
char *p, *pn, *pdb;
|
|
PTABLE tbl;
|
|
|
|
for (pdb = tablist; ;) {
|
|
if ((p = strchr(pdb, ',')))
|
|
*p = 0;
|
|
|
|
// Analyze the table name, it may have the format:
|
|
// [dbname.]tabname
|
|
if ((pn = strchr(pdb, '.'))) {
|
|
*pn++ = 0;
|
|
} else {
|
|
pn = pdb;
|
|
pdb = dbname;
|
|
} // endif p
|
|
|
|
// Allocate the TBLIST block for that table
|
|
tbl = new(g) XTAB(pn, def);
|
|
tbl->SetSchema(pdb);
|
|
|
|
if (trace(1))
|
|
htrc("TBL: Name=%s db=%s\n", tbl->GetName(), tbl->GetSchema());
|
|
|
|
// Link the blocks
|
|
if (Tablep)
|
|
Tablep->Link(tbl);
|
|
else
|
|
Tablep = tbl;
|
|
|
|
Ntables++;
|
|
|
|
if (p)
|
|
pdb = pn + strlen(pn) + 1;
|
|
else
|
|
break;
|
|
|
|
} // endfor pdb
|
|
|
|
Maxerr = GetIntCatInfo("Maxerr", 0);
|
|
Accept = GetBoolCatInfo("Accept", false);
|
|
Thread = GetBoolCatInfo("Thread", false);
|
|
} // endif tablist
|
|
|
|
return FALSE;
|
|
} // end of DefineAM
|
|
|
|
/***********************************************************************/
|
|
/* GetTable: makes a new Table Description Block. */
|
|
/***********************************************************************/
|
|
PTDB TBLDEF::GetTable(PGLOBAL g, MODE)
|
|
{
|
|
if (Catfunc == FNC_COL)
|
|
return new(g) TDBTBC(this);
|
|
else if (Thread) {
|
|
#if defined(DEVELOPMENT)
|
|
return new(g) TDBTBM(this);
|
|
#else
|
|
strcpy(g->Message, "Option THREAD is no more supported");
|
|
return NULL;
|
|
#endif // DEVELOPMENT
|
|
} else
|
|
return new(g) TDBTBL(this);
|
|
|
|
} // end of GetTable
|
|
|
|
/* ------------------------- Class TDBTBL ---------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* TDBTBL constructors. */
|
|
/***********************************************************************/
|
|
TDBTBL::TDBTBL(PTBLDEF tdp) : TDBPRX(tdp)
|
|
{
|
|
Tablist = NULL;
|
|
CurTable = NULL;
|
|
//Tdbp = NULL;
|
|
Accept = tdp->Accept;
|
|
Maxerr = tdp->Maxerr;
|
|
Nbc = 0;
|
|
Rows = 0;
|
|
Crp = 0;
|
|
// NTables = 0;
|
|
// iTable = 0;
|
|
} // end of TDBTBL standard constructor
|
|
|
|
/***********************************************************************/
|
|
/* Allocate TBL column description block. */
|
|
/***********************************************************************/
|
|
PCOL TDBTBL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
|
{
|
|
return new(g) PRXCOL(cdp, this, cprec, n);
|
|
} // end of MakeCol
|
|
|
|
/***********************************************************************/
|
|
/* InsertSpecialColumn: Put a special column ahead of the column list.*/
|
|
/***********************************************************************/
|
|
PCOL TDBTBL::InsertSpecialColumn(PCOL scp)
|
|
{
|
|
PCOL colp;
|
|
|
|
if (!scp->IsSpecial())
|
|
return NULL;
|
|
|
|
if (scp->GetAmType() == TYPE_AM_TABID)
|
|
// This special column is handled locally
|
|
colp = new((TIDBLK*)scp) TBTBLK(scp->GetValue());
|
|
else // Other special columns are treated normally
|
|
colp = scp;
|
|
|
|
colp->SetNext(Columns);
|
|
Columns = colp;
|
|
return colp;
|
|
} // end of InsertSpecialColumn
|
|
|
|
/***********************************************************************/
|
|
/* Initializes the table table list. */
|
|
/***********************************************************************/
|
|
bool TDBTBL::InitTableList(PGLOBAL g)
|
|
{
|
|
uint sln;
|
|
const char *scs;
|
|
PTABLE tp, tabp;
|
|
PCOL colp;
|
|
PTBLDEF tdp = (PTBLDEF)To_Def;
|
|
PCATLG cat = To_Def->GetCat();
|
|
PHC hc = ((MYCAT*)cat)->GetHandler();
|
|
|
|
scs = hc->get_table()->s->connect_string.str;
|
|
sln = hc->get_table()->s->connect_string.length;
|
|
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
|
|
|
for (tp = tdp->Tablep; tp; tp = tp->GetNext()) {
|
|
if (TestFil(g, To_CondFil, tp)) {
|
|
tabp = new(g) XTAB(tp);
|
|
|
|
if (tabp->GetSrc()) {
|
|
// Table list is a list of connections
|
|
hc->get_table()->s->connect_string.str = (char*)tabp->GetName();
|
|
hc->get_table()->s->connect_string.length = strlen(tabp->GetName());
|
|
} // endif Src
|
|
|
|
// Get the table description block of this table
|
|
if (!(Tdbp = GetSubTable(g, tabp))) {
|
|
if (++Nbc > Maxerr)
|
|
return TRUE; // Error return
|
|
else
|
|
continue; // Skip this table
|
|
|
|
} else
|
|
RemoveNext(tabp); // To avoid looping
|
|
|
|
// We must allocate subtable columns before GetMaxSize is called
|
|
// because some (PLG, ODBC?) need to have their columns attached.
|
|
// Real initialization will be done later.
|
|
for (colp = Columns; colp; colp = colp->GetNext())
|
|
if (!colp->IsSpecial())
|
|
if (((PPRXCOL)colp)->Init(g, NULL) && !Accept)
|
|
return TRUE;
|
|
|
|
if (Tablist)
|
|
Tablist->Link(tabp);
|
|
else
|
|
Tablist = tabp;
|
|
|
|
} // endif filp
|
|
|
|
} // endfor tp
|
|
|
|
hc->get_table()->s->connect_string.str = (char*)scs;
|
|
hc->get_table()->s->connect_string.length = sln;
|
|
|
|
//NumTables = n;
|
|
To_CondFil = NULL; // To avoid doing it several times
|
|
return FALSE;
|
|
} // end of InitTableList
|
|
|
|
/***********************************************************************/
|
|
/* Test the tablename against the pseudo "local" filter. */
|
|
/***********************************************************************/
|
|
bool TDBTBL::TestFil(PGLOBAL g, PCFIL filp, PTABLE tabp)
|
|
{
|
|
char *body, *fil, op[8], tn[NAME_LEN];
|
|
bool neg;
|
|
|
|
if (!filp)
|
|
return TRUE;
|
|
else
|
|
body = filp->Body;
|
|
|
|
if (strstr(body, " OR ") || strstr(body, " AND "))
|
|
return TRUE; // Not handled yet
|
|
else
|
|
fil = body + (*body == '(' ? 1 : 0);
|
|
|
|
if (sscanf(fil, "TABID %s", op) != 1)
|
|
return TRUE; // ignore invalid filter
|
|
|
|
if ((neg = !strcmp(op, "NOT")))
|
|
strcpy(op, "IN");
|
|
|
|
if (!strcmp(op, "=")) {
|
|
// Temporarily, filter must be "TABID = 'value'" only
|
|
if (sscanf(fil, "TABID = '%[^']'", tn) != 1)
|
|
return TRUE; // ignore invalid filter
|
|
|
|
return !stricmp(tn, tabp->GetName());
|
|
} else if (!strcmp(op, "IN")) {
|
|
char *p, *tnl = (char*)PlugSubAlloc(g, NULL, strlen(fil) - 10);
|
|
int n;
|
|
|
|
if (neg)
|
|
n = sscanf(fil, "TABID NOT IN (%[^)])", tnl);
|
|
else
|
|
n = sscanf(fil, "TABID IN (%[^)])", tnl);
|
|
|
|
if (n != 1)
|
|
return TRUE; // ignore invalid filter
|
|
|
|
while (tnl) {
|
|
if ((p = strchr(tnl, ',')))
|
|
*p++ = 0;
|
|
|
|
if (sscanf(tnl, "'%[^']'", tn) != 1)
|
|
return TRUE; // ignore invalid filter
|
|
else if (!stricmp(tn, tabp->GetName()))
|
|
return !neg; // Found
|
|
|
|
tnl = p;
|
|
} // endwhile
|
|
|
|
return neg; // Not found
|
|
} // endif op
|
|
|
|
return TRUE; // invalid operator
|
|
} // end of TestFil
|
|
|
|
/***********************************************************************/
|
|
/* Sum up the cardinality of all sub-tables. */
|
|
/***********************************************************************/
|
|
int TDBTBL::Cardinality(PGLOBAL g)
|
|
{
|
|
if (!g)
|
|
return 0; // Cannot make the table list
|
|
else if (Cardinal < 0) {
|
|
int tsz;
|
|
|
|
if (!Tablist && InitTableList(g))
|
|
return 0; // Cannot be calculated at this stage
|
|
|
|
Cardinal = 0;
|
|
|
|
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext()) {
|
|
if ((tsz = tabp->GetTo_Tdb()->Cardinality(g)) < 0) {
|
|
Cardinal = -1;
|
|
return tsz;
|
|
} // endif mxsz
|
|
|
|
Cardinal += tsz;
|
|
} // endfor i
|
|
|
|
} // endif Cardinal
|
|
|
|
return Cardinal;
|
|
} // end of Cardinality
|
|
|
|
/***********************************************************************/
|
|
/* Sum up the maximum sizes of all sub-tables. */
|
|
/***********************************************************************/
|
|
int TDBTBL::GetMaxSize(PGLOBAL g)
|
|
{
|
|
if (MaxSize < 0) {
|
|
int mxsz;
|
|
|
|
if (!Tablist && InitTableList(g))
|
|
return 0; // Cannot be calculated at this stage
|
|
|
|
MaxSize = 0;
|
|
|
|
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext()) {
|
|
if ((mxsz = tabp->GetTo_Tdb()->GetMaxSize(g)) < 0) {
|
|
MaxSize = -1;
|
|
return mxsz;
|
|
} // endif mxsz
|
|
|
|
MaxSize += mxsz;
|
|
} // endfor i
|
|
|
|
} // endif MaxSize
|
|
|
|
return MaxSize;
|
|
} // end of GetMaxSize
|
|
|
|
/***********************************************************************/
|
|
/* Reset read/write position values. */
|
|
/***********************************************************************/
|
|
void TDBTBL::ResetDB(void)
|
|
{
|
|
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
|
if (colp->GetAmType() == TYPE_AM_TABID ||
|
|
colp->GetAmType() == TYPE_AM_SRVID)
|
|
colp->COLBLK::Reset();
|
|
|
|
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext())
|
|
tabp->GetTo_Tdb()->ResetDB();
|
|
|
|
Tdbp = Tablist->GetTo_Tdb();
|
|
Crp = 0;
|
|
} // end of ResetDB
|
|
|
|
/***********************************************************************/
|
|
/* Returns RowId if b is false or Rownum if b is true. */
|
|
/***********************************************************************/
|
|
int TDBTBL::RowNumber(PGLOBAL g, bool b)
|
|
{
|
|
return Tdbp->RowNumber(g) + ((b) ? 0 : Rows);
|
|
} // end of RowNumber
|
|
|
|
/***********************************************************************/
|
|
/* TBL Access Method opening routine. */
|
|
/* Open first file, other will be opened sequencially when reading. */
|
|
/***********************************************************************/
|
|
bool TDBTBL::OpenDB(PGLOBAL g)
|
|
{
|
|
if (trace(1))
|
|
htrc("TBL OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
|
|
this, Tdb_No, Use, To_Key_Col, Mode);
|
|
|
|
if (Use == USE_OPEN) {
|
|
/*******************************************************************/
|
|
/* Table already open, replace it at its beginning. */
|
|
/*******************************************************************/
|
|
ResetDB();
|
|
return Tdbp->OpenDB(g); // Re-open fist table
|
|
} // endif use
|
|
|
|
/*********************************************************************/
|
|
/* When GetMaxsize was called, To_CondFil was not set yet. */
|
|
/*********************************************************************/
|
|
if (To_CondFil && Tablist) {
|
|
Tablist = NULL;
|
|
Nbc = 0;
|
|
} // endif To_CondFil
|
|
|
|
/*********************************************************************/
|
|
/* Open the first table of the list. */
|
|
/*********************************************************************/
|
|
if (!Tablist && InitTableList(g)) // done in GetMaxSize
|
|
return TRUE;
|
|
|
|
if ((CurTable = Tablist)) {
|
|
Tdbp = CurTable->GetTo_Tdb();
|
|
// Tdbp->SetMode(Mode);
|
|
// Tdbp->ResetDB();
|
|
// Tdbp->ResetSize();
|
|
|
|
// Check and initialize the subtable columns
|
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
|
if (cp->GetAmType() == TYPE_AM_TABID)
|
|
cp->COLBLK::Reset();
|
|
else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
|
|
return TRUE;
|
|
|
|
if (trace(1))
|
|
htrc("Opening subtable %s\n", Tdbp->GetName());
|
|
|
|
// Now we can safely open the table
|
|
if (Tdbp->OpenDB(g))
|
|
return TRUE;
|
|
|
|
} // endif *Tablist
|
|
|
|
Use = USE_OPEN;
|
|
return FALSE;
|
|
} // end of OpenDB
|
|
|
|
/***********************************************************************/
|
|
/* ReadDB: Data Base read routine for MUL access method. */
|
|
/***********************************************************************/
|
|
int TDBTBL::ReadDB(PGLOBAL g)
|
|
{
|
|
int rc;
|
|
|
|
if (!CurTable)
|
|
return RC_EF;
|
|
else if (To_Kindex) {
|
|
/*******************************************************************/
|
|
/* Reading is by an index table. */
|
|
/*******************************************************************/
|
|
strcpy(g->Message, MSG(NO_INDEX_READ));
|
|
rc = RC_FX;
|
|
} else {
|
|
/*******************************************************************/
|
|
/* Now start the reading process. */
|
|
/*******************************************************************/
|
|
retry:
|
|
rc = Tdbp->ReadDB(g);
|
|
|
|
if (rc == RC_EF) {
|
|
// Total number of rows met so far
|
|
Rows += Tdbp->RowNumber(g) - 1;
|
|
Crp += Tdbp->GetProgMax(g);
|
|
|
|
if ((CurTable = CurTable->GetNext())) {
|
|
/***************************************************************/
|
|
/* Continue reading from next table file. */
|
|
/***************************************************************/
|
|
Tdbp->CloseDB(g);
|
|
Tdbp = CurTable->GetTo_Tdb();
|
|
|
|
// Check and initialize the subtable columns
|
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
|
if (cp->GetAmType() == TYPE_AM_TABID ||
|
|
cp->GetAmType() == TYPE_AM_SRVID)
|
|
cp->COLBLK::Reset();
|
|
else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
|
|
return RC_FX;
|
|
|
|
if (trace(1))
|
|
htrc("Opening subtable %s\n", Tdbp->GetName());
|
|
|
|
// Now we can safely open the table
|
|
if (Tdbp->OpenDB(g)) // Open next table
|
|
return RC_FX;
|
|
|
|
goto retry;
|
|
} // endif iFile
|
|
|
|
} else if (rc == RC_FX)
|
|
strcat(strcat(strcat(g->Message, " ("), Tdbp->GetName()), ")");
|
|
|
|
} // endif To_Kindex
|
|
|
|
return rc;
|
|
} // end of ReadDB
|
|
|
|
/* ---------------------------- TBTBLK ------------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* ReadColumn: */
|
|
/***********************************************************************/
|
|
void TBTBLK::ReadColumn(PGLOBAL)
|
|
{
|
|
if (trace(1))
|
|
htrc("TBT ReadColumn: name=%s\n", Name);
|
|
|
|
Value->SetValue_psz((char*)((PTDBTBL)To_Tdb)->Tdbp->GetName());
|
|
|
|
} // end of ReadColumn
|
|
|
|
#if defined(DEVELOPMENT)
|
|
/* ------------------------- Class TDBTBM ---------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* Thread routine that check and open one remote connection. */
|
|
/***********************************************************************/
|
|
pthread_handler_t ThreadOpen(void *p)
|
|
{
|
|
PTBMT cmp = (PTBMT)p;
|
|
|
|
if (!my_thread_init()) {
|
|
set_current_thd(cmp->Thd);
|
|
|
|
if (trace(1))
|
|
htrc("ThreadOpen: Thd=%d\n", cmp->Thd);
|
|
|
|
// Try to open the connection
|
|
pthread_mutex_lock(&tblmut);
|
|
|
|
if (!cmp->Tap->GetTo_Tdb()->OpenDB(cmp->G)) {
|
|
// pthread_mutex_lock(&tblmut);
|
|
if (trace(1))
|
|
htrc("Table %s ready\n", cmp->Tap->GetName());
|
|
|
|
cmp->Ready = true;
|
|
// pthread_mutex_unlock(&tblmut);
|
|
} else {
|
|
// pthread_mutex_lock(&tblmut);
|
|
if (trace(1))
|
|
htrc("Opening %s failed\n", cmp->Tap->GetName());
|
|
|
|
cmp->Rc = RC_FX;
|
|
// pthread_mutex_unlock(&tblmut);
|
|
} // endif OpenDB
|
|
|
|
pthread_mutex_unlock(&tblmut);
|
|
my_thread_end();
|
|
} else
|
|
cmp->Rc = RC_FX;
|
|
|
|
return NULL;
|
|
} // end of ThreadOpen
|
|
|
|
/***********************************************************************/
|
|
/* TDBTBM constructors. */
|
|
/***********************************************************************/
|
|
TDBTBM::TDBTBM(PTBLDEF tdp) : TDBTBL(tdp)
|
|
{
|
|
Tmp = NULL; // To data table TBMT structures
|
|
Cmp = NULL; // Current data table TBMT
|
|
Bmp = NULL; // To bad (unconnected) TBMT structures
|
|
Done = false; // TRUE after first GetAllResults
|
|
Nrc = 0; // Number of remote connections
|
|
Nlc = 0; // Number of local connections
|
|
} // end of TDBTBL standard constructor
|
|
|
|
/***********************************************************************/
|
|
/* Reset read/write position values. */
|
|
/***********************************************************************/
|
|
void TDBTBM::ResetDB(void)
|
|
{
|
|
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
|
if (colp->GetAmType() == TYPE_AM_TABID)
|
|
colp->COLBLK::Reset();
|
|
|
|
// Local tables
|
|
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext())
|
|
tabp->GetTo_Tdb()->ResetDB();
|
|
|
|
// Remote tables
|
|
for (PTBMT tp = Tmp; tp; tp = tp->Next)
|
|
tp->Tap->GetTo_Tdb()->ResetDB();
|
|
|
|
Tdbp = (Tablist) ? Tablist->GetTo_Tdb() : NULL;
|
|
Crp = 0;
|
|
} // end of ResetDB
|
|
|
|
/***********************************************************************/
|
|
/* Returns RowId if b is false or Rownum if b is true. */
|
|
/***********************************************************************/
|
|
int TDBTBM::RowNumber(PGLOBAL g, bool b)
|
|
{
|
|
return Tdbp->RowNumber(g) + ((b) ? 0 : Rows);
|
|
} // end of RowNumber
|
|
|
|
/***********************************************************************/
|
|
/* Returns true if this MYSQL table refers to a local table. */
|
|
/***********************************************************************/
|
|
bool TDBTBM::IsLocal(PTABLE tbp)
|
|
{
|
|
TDBMYSQL *tdbp = (TDBMYSQL*)tbp->GetTo_Tdb();
|
|
|
|
return ((!stricmp(tdbp->Host, "localhost") ||
|
|
!strcmp(tdbp->Host, "127.0.0.1")) &&
|
|
(int) tdbp->Port == (int)GetDefaultPort());
|
|
} // end of IsLocal
|
|
|
|
/***********************************************************************/
|
|
/* Initialyze table parallel processing. */
|
|
/***********************************************************************/
|
|
bool TDBTBM::OpenTables(PGLOBAL g)
|
|
{
|
|
int k;
|
|
THD *thd = current_thd;
|
|
PTABLE tabp, *ptabp = &Tablist;
|
|
PTBMT tp, *ptp = &Tmp;
|
|
|
|
// Allocates the TBMT blocks for the tables
|
|
for (tabp = Tablist; tabp; tabp = tabp->Next)
|
|
if (tabp->GetTo_Tdb()->GetAmType() == TYPE_AM_MYSQL && !IsLocal(tabp)) {
|
|
// Remove remote table from the local list
|
|
*ptabp = tabp->Next;
|
|
|
|
if (trace(1))
|
|
htrc("=====> New remote table %s\n", tabp->GetName());
|
|
|
|
// Make the remote table block
|
|
tp = (PTBMT)PlugSubAlloc(g, NULL, sizeof(TBMT));
|
|
memset(tp, 0, sizeof(TBMT));
|
|
tp->G = g;
|
|
tp->Ready = false;
|
|
tp->Tap = tabp;
|
|
tp->Thd = thd;
|
|
|
|
// Create the thread that will do the table opening.
|
|
pthread_attr_init(&tp->attr);
|
|
// pthread_attr_setdetachstate(&tp->attr, PTHREAD_CREATE_JOINABLE);
|
|
|
|
if ((k = pthread_create(&tp->Tid, &tp->attr, ThreadOpen, tp))) {
|
|
snprintf(g->Message, sizeof(g->Message), "pthread_create error %d", k);
|
|
Nbc++;
|
|
continue;
|
|
} // endif k
|
|
|
|
// Add it to the remote list
|
|
*ptp = tp;
|
|
ptp = &tp->Next;
|
|
Nrc++; // Number of remote connections
|
|
} else {
|
|
if (trace(1))
|
|
htrc("=====> Local table %s\n", tabp->GetName());
|
|
|
|
ptabp = &tabp->Next;
|
|
Nlc++; // Number of local connections
|
|
} // endif Type
|
|
|
|
return false;
|
|
} // end of OpenTables
|
|
|
|
/***********************************************************************/
|
|
/* TBL Access Method opening routine. */
|
|
/* Open first file, other will be opened sequencially when reading. */
|
|
/***********************************************************************/
|
|
bool TDBTBM::OpenDB(PGLOBAL g)
|
|
{
|
|
if (trace(1))
|
|
htrc("TBM OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
|
|
this, Tdb_No, Use, To_Key_Col, Mode);
|
|
|
|
if (Use == USE_OPEN) {
|
|
/*******************************************************************/
|
|
/* Table already open, replace it at its beginning. */
|
|
/*******************************************************************/
|
|
ResetDB();
|
|
return (Tdbp) ? Tdbp->OpenDB(g) : false; // Re-open fist table
|
|
} // endif use
|
|
|
|
#if 0
|
|
/*********************************************************************/
|
|
/* When GetMaxsize was called, To_CondFil was not set yet. */
|
|
/*********************************************************************/
|
|
if (To_CondFil && Tablist) {
|
|
Tablist = NULL;
|
|
Nbc = 0;
|
|
} // endif To_CondFil
|
|
#endif // 0
|
|
|
|
/*********************************************************************/
|
|
/* Make the table list. */
|
|
/*********************************************************************/
|
|
if (/*!Tablist &&*/ InitTableList(g))
|
|
return TRUE;
|
|
|
|
/*********************************************************************/
|
|
/* Open all remote tables of the list. */
|
|
/*********************************************************************/
|
|
if (OpenTables(g))
|
|
return TRUE;
|
|
|
|
/*********************************************************************/
|
|
/* Proceed with local tables. */
|
|
/*********************************************************************/
|
|
if ((CurTable = Tablist)) {
|
|
Tdbp = CurTable->GetTo_Tdb();
|
|
// Tdbp->SetMode(Mode);
|
|
|
|
// Check and initialize the subtable columns
|
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
|
if (cp->GetAmType() == TYPE_AM_TABID)
|
|
cp->COLBLK::Reset();
|
|
else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
|
|
return TRUE;
|
|
|
|
if (trace(1))
|
|
htrc("Opening subtable %s\n", Tdbp->GetName());
|
|
|
|
// Now we can safely open the table
|
|
if (Tdbp->OpenDB(g))
|
|
return TRUE;
|
|
|
|
} // endif *Tablist
|
|
|
|
Use = USE_OPEN;
|
|
return FALSE;
|
|
} // end of OpenDB
|
|
|
|
/***********************************************************************/
|
|
/* ReadDB: Data Base read routine for MUL access method. */
|
|
/***********************************************************************/
|
|
int TDBTBM::ReadDB(PGLOBAL g)
|
|
{
|
|
int rc;
|
|
|
|
if (!Done) {
|
|
// Get result from local tables
|
|
if ((rc = TDBTBL::ReadDB(g)) != RC_EF)
|
|
return rc;
|
|
else if ((rc = ReadNextRemote(g)) != RC_OK)
|
|
return rc;
|
|
|
|
Done = true;
|
|
} // endif Done
|
|
|
|
/*********************************************************************/
|
|
/* Now start the reading process of remote tables. */
|
|
/*********************************************************************/
|
|
retry:
|
|
rc = Tdbp->ReadDB(g);
|
|
|
|
if (rc == RC_EF) {
|
|
// Total number of rows met so far
|
|
Rows += Tdbp->RowNumber(g) - 1;
|
|
Crp += Tdbp->GetProgMax(g);
|
|
Cmp->Complete = true;
|
|
|
|
if ((rc = ReadNextRemote(g)) == RC_OK)
|
|
goto retry;
|
|
|
|
} else if (rc == RC_FX)
|
|
strcat(strcat(strcat(g->Message, " ("), Tdbp->GetName()), ")");
|
|
|
|
return rc;
|
|
} // end of ReadDB
|
|
|
|
/***********************************************************************/
|
|
/* ReadNext: Continue reading from next table. */
|
|
/***********************************************************************/
|
|
int TDBTBM::ReadNextRemote(PGLOBAL g)
|
|
{
|
|
bool b;
|
|
|
|
if (Tdbp)
|
|
Tdbp->CloseDB(g);
|
|
|
|
Cmp = NULL;
|
|
|
|
retry:
|
|
b = false;
|
|
|
|
// Search for a remote table having its result set
|
|
pthread_mutex_lock(&tblmut);
|
|
for (PTBMT tp = Tmp; tp; tp = tp->Next)
|
|
if (tp->Rc != RC_FX) {
|
|
if (tp->Ready) {
|
|
if (!tp->Complete) {
|
|
Cmp = tp;
|
|
break;
|
|
} // endif Complete
|
|
|
|
} else
|
|
b = true;
|
|
|
|
} // endif Rc
|
|
|
|
pthread_mutex_unlock(&tblmut);
|
|
|
|
if (!Cmp) {
|
|
if (b) { // more result to come
|
|
// sleep(20);
|
|
goto retry;
|
|
} else
|
|
return RC_EF;
|
|
|
|
} // endif Curtable
|
|
|
|
Tdbp = Cmp->Tap->GetTo_Tdb();
|
|
|
|
// Check and initialize the subtable columns
|
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
|
if (cp->GetAmType() == TYPE_AM_TABID)
|
|
cp->COLBLK::Reset();
|
|
else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
|
|
return RC_FX;
|
|
|
|
if (trace(1))
|
|
htrc("Reading subtable %s\n", Tdbp->GetName());
|
|
|
|
return RC_OK;
|
|
} // end of ReadNextRemote
|
|
#endif // DEVELOPMENT
|
|
|
|
/* ------------------------------------------------------------------- */
|