mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 10:56:12 +01:00 
			
		
		
		
	 56948ee54c
			
		
	
	
	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
 | |
| 
 | |
| /* ------------------------------------------------------------------- */
 |