From 30c4b0ebc24fe0106e146b1f6577a4150e71e258 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 7 Feb 2013 13:34:27 +0400 Subject: - Fixing TAB to 2 spaces - Fixing line endings from "\r\n" to "\n" --- storage/connect/tabtbl.cpp | 1554 ++++++++++++++++++++++---------------------- 1 file changed, 777 insertions(+), 777 deletions(-) (limited to 'storage/connect/tabtbl.cpp') diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp index 9f4bb8a05a8..4abdb7aa681 100644 --- a/storage/connect/tabtbl.cpp +++ b/storage/connect/tabtbl.cpp @@ -1,777 +1,777 @@ -/************* TabTbl C++ Program Source Code File (.CPP) **************/ -/* PROGRAM NAME: TABTBL */ -/* ------------- */ -/* Version 1.3 */ -/* */ -/* COPYRIGHT: */ -/* ---------- */ -/* (C) Copyright to PlugDB Software Development 2008-2012 */ -/* Author: Olivier BERTRAND */ -/* */ -/* 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" -#if defined(WIN32) -#include -#include -#if defined(__BORLANDC__) -#define __MFC_COMPAT__ // To define min/max as macro -#endif -//#include -#else -#if defined(UNIX) -#include -#include -#include -#include -#include -#include "osutil.h" -#else -//#include -#endif -//#include -#endif - -/***********************************************************************/ -/* Include application header files: */ -/***********************************************************************/ -#include "table.h" // MySQL table definitions -#include "global.h" // global declarations -#include "plgdbsem.h" // DB application declarations -#include "reldef.h" // DB definition declares -//#include "filter.h" // FILTER classes dcls -#include "filamtxt.h" -#include "tabcol.h" -#include "tabdos.h" // TDBDOS and DOSCOL class dcls -#include "tabtbl.h" // TDBTBL and TBLCOL classes dcls -#include "ha_connect.h" -#include "mycat.h" // For GetHandler - -extern "C" int trace; - -int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags); - -/* ---------------------------- Class TBLDEF ---------------------------- */ - -/**************************************************************************/ -/* Constructor. */ -/**************************************************************************/ -TBLDEF::TBLDEF(void) - { - To_Tables = NULL; - Ntables = 0; - Pseudo = 3; - } // end of TBLDEF constructor - -/**************************************************************************/ -/* DefineAM: define specific AM block values from XDB file. */ -/**************************************************************************/ -bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) - { - char *tablist, *dbname; - - Desc = "Table list table"; - tablist = Cat->GetStringCatInfo(g, Name, "Tablist", ""); - dbname = Cat->GetStringCatInfo(g, Name, "Database", NULL); - Ntables = 0; - - if (*tablist) { - char *p, *pn, *pdb; - PTBL *ptbl = &To_Tables, tbl; - - for (pdb = tablist; ;) { - if ((p = strchr(pdb, ','))) - *p = 0; - - // Analyze the table name, it has 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 = (PTBL)PlugSubAlloc(g, NULL, sizeof(TBLIST)); - tbl->Next = NULL; - tbl->Name = pn; - tbl->DB = pdb; - - if (trace) - htrc("TBL: Name=%s db=%s\n", tbl->Name, SVP(tbl->DB)); - - // Link the blocks - *ptbl = tbl; - ptbl = &tbl->Next; - Ntables++; - - if (p) - pdb = pn + strlen(pn) + 1; - else - break; - - } // endfor pdb - - Maxerr = Cat->GetIntCatInfo(Name, "Maxerr", 0); - Accept = (Cat->GetBoolCatInfo(Name, "Accept", 0) != 0); - } // endif fsec || tablist - - return FALSE; - } // end of DefineAM - -/***********************************************************************/ -/* GetTable: makes a new Table Description Block. */ -/***********************************************************************/ -PTDB TBLDEF::GetTable(PGLOBAL g, MODE m) - { - PTDB tdbp; - - /*********************************************************************/ - /* Allocate a TDB of the proper type. */ - /* Column blocks will be allocated only when needed. */ - /*********************************************************************/ - tdbp = new(g) TDBTBL(this); - - return tdbp; - } // end of GetTable - -/* ------------------------- Class TDBTBL ---------------------------- */ - -/***********************************************************************/ -/* TDBTBL constructors. */ -/***********************************************************************/ -TDBTBL::TDBTBL(PTBLDEF tdp) : TDBASE(tdp) - { - Tablist = NULL; - CurTable = NULL; - Tdbp = NULL; - Accept = tdp->Accept; - Maxerr = tdp->Maxerr; - Nbf = 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) TBLCOL(cdp, this, cprec, n); - } // end of MakeCol - -/***********************************************************************/ -/* InsertSpecialColumn: Put a special column ahead of the column list.*/ -/***********************************************************************/ -PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, 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 - -/***********************************************************************/ -/* Get the PTDB of a table of the list. */ -/***********************************************************************/ -PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp) - { - char *db, key[128]; - uint k, flags; - PTDB tdbp = NULL; - TABLE_LIST table_list; - TABLE_SHARE *s; - PCATLG cat = To_Def->GetCat(); - PHC hc = ((MYCAT*)cat)->GetHandler(); - THD *thd = (hc->GetTable())->in_use; - - if (!thd) - return NULL; // Should not happen anymore - - if (tblp->DB) - db = tblp->DB; - else - db = (char*)hc->GetDBName(NULL); - - table_list.init_one_table(db, strlen(db), - tblp->Name, strlen(tblp->Name), - NULL, TL_IGNORE); - k = sprintf(key, "%s\0%s\0", db, tblp->Name); - - if (!(s = alloc_table_share(&table_list, key, k))) { - strcpy(g->Message, "Error allocating share\n"); - return NULL; - } // endif s - -// 1 8 16 -//flags = READ_ALL | DONT_OPEN_TABLES | DONT_OPEN_MASTER_REG; -//flags = 25; - flags = 24; - - if (!open_table_def(thd, s, flags)) { - hc->tshp = s; - tdbp = cat->GetTable(g, tabp); - hc->tshp = NULL; - } else - sprintf(g->Message, "Error %d opening share\n", s->error); - - if (trace && tdbp) - htrc("Subtable %s in %s\n", - tblp->Name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB())); - - free_table_share(s); - return tdbp; - } // end of GetSubTable - -/***********************************************************************/ -/* Initializes the table table list. */ -/***********************************************************************/ -bool TDBTBL::InitTableList(PGLOBAL g) - { - char *colname; - int n, colpos; - PTBL tblp; - PTABLE tabp; - PTDB tdbp; - PCOL colp; - PTBLDEF tdp = (PTBLDEF)To_Def; - -// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath()); - - for (n = 0, tblp = tdp->GetTables(); tblp; tblp = tblp->Next) { - if (TestFil(g, To_Filter, tblp)) { - // Table or named view - tabp = new(g) XTAB(tblp->Name); - tabp->SetQualifier(tblp->DB); - - // Get the table description block of this table - if (!(tdbp = GetSubTable(g, tblp, tabp))) { - if (++Nbf > Maxerr) - return TRUE; // Error return - else - continue; // Skip this table - - } // endif tdbp - - // 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 (PCOL cp = Columns; cp; cp = cp->GetNext()) - if (!cp->IsSpecial()) { - colname = cp->GetName(); - colpos = ((PTBLCOL)cp)->Colnum; - - // We try first to get the column by name - if (!(colp = tdbp->ColDB(g, colname, 0)) && colpos) - // When unsuccessful, if a column number was specified - // try to get the column by its position in the table - colp = tdbp->ColDB(g, NULL, colpos); - - if (!colp) { - if (!Accept) { - sprintf(g->Message, MSG(NO_MATCHING_COL), - colname, tdbp->GetName()); - return TRUE; // Error return - } // endif !Accept - - } else // this is needed in particular by PLG tables - colp->SetColUse(cp->GetColUse()); - - } // endif !special - - if (Tablist) - Tablist->Link(tabp); - else - Tablist = tabp; - - n++; - } // endif filp - - } // endfor tblp - -//NumTables = n; - To_Filter = 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, PFIL filp, PTBL tblp) - { - char *fil, op[8], tn[NAME_LEN]; - bool neg; - - if (!filp) - return TRUE; - else if (strstr(filp, " OR ") || strstr(filp, " AND ")) - return TRUE; // Not handled yet - else - fil = filp + (*filp == '(' ? 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, tblp->Name); - } 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, tblp->Name)) - return !neg; // Found - - tnl = p; - } // endwhile - - return neg; // Not found - } // endif op - - return TRUE; // invalid operator - } // end of TestFil - -/***********************************************************************/ -/* TBL GetProgMax: get the max value for progress information. */ -/***********************************************************************/ -int TDBTBL::GetProgMax(PGLOBAL g) - { - PTABLE tblp; - int n, pmx = 0; - - if (!Tablist && InitTableList(g)) - return -1; - - for (tblp = Tablist; tblp; tblp = tblp->GetNext()) - if ((n = tblp->GetTo_Tdb()->GetProgMax(g)) > 0) - pmx += n; - - return pmx; - } // end of GetProgMax - -/***********************************************************************/ -/* TBL GetProgCur: get the current value for progress information. */ -/***********************************************************************/ -int TDBTBL::GetProgCur(void) - { - return Crp + Tdbp->GetProgCur(); - } // end of GetProgCur - -#if 0 -/***********************************************************************/ -/* TBL Cardinality: returns table cardinality in number of rows. */ -/* This function can be called with a null argument to test the */ -/* availability of Cardinality implementation (1 yes, 0 no). */ -/* Can be used on Multiple FIX table only. */ -/***********************************************************************/ -int TDBTBL::Cardinality(PGLOBAL g) - { - if (!g) - return Tdbp->Cardinality(g); - - if (!Tablist && InitTableList(g)) - return -1; - - int n, card = 0; - - for (int i = 0; i < NumFiles; i++) { - Tdbp->SetFile(g, Filenames[i]); - Tdbp->ResetSize(); - - if ((n = Tdbp->Cardinality(g)) < 0) { -// strcpy(g->Message, MSG(BAD_CARDINALITY)); - return -1; - } // endif n - - card += n; - } // endfor i - - return card; - } // end of Cardinality -#endif // 0 - -/***********************************************************************/ -/* Sum up the sizes of all sub-tables. */ -/***********************************************************************/ -int TDBTBL::GetMaxSize(PGLOBAL g) - { - if (MaxSize < 0) { - PTABLE tblp; - int mxsz; - - if (!Tablist && InitTableList(g)) - return 0; // Cannot be calculated at this stage - -// if (Use == USE_OPEN) { -// strcpy(g->Message, MSG(MAXSIZE_ERROR)); -// return -1; -// } else - MaxSize = 0; - - for (tblp = Tablist; tblp; tblp = tblp->GetNext()) { - if ((mxsz = tblp->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->COLBLK::Reset(); - - for (PTABLE tblp = Tablist; tblp; tblp = tblp->GetNext()) - ((PTDBASE)tblp->GetTo_Tdb())->ResetDB(); - - Tdbp = (PTDBASE)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) - 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 - -#if 0 - /*********************************************************************/ - /* Direct access needed for join or sorting. */ - /*********************************************************************/ - if (NeedIndexing(g)) { - // Direct access of TBL tables is not implemented yet - strcpy(g->Message, MSG(NO_MUL_DIR_ACC)); - return TRUE; - } // endif NeedIndexing -#endif // 0 - - /*********************************************************************/ - /* When GetMaxsize was called, To_Filter was not set yet. */ - /*********************************************************************/ - if (To_Filter && Tablist) { - Tablist = NULL; - Nbf = 0; - } // endif To_Filter - - /*********************************************************************/ - /* Open the first table of the list. */ - /*********************************************************************/ - if (!Tablist && InitTableList(g)) // done in GetMaxSize - return TRUE; - - if ((CurTable = Tablist)) { - Tdbp = (PTDBASE)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 (((PTBLCOL)cp)->Init(g)) - return TRUE; - - if (trace) - 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 = (PTDBASE)CurTable->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 (((PTBLCOL)cp)->Init(g)) - return RC_FX; - - if (trace) - 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 - -/***********************************************************************/ -/* Data Base write routine for MUL access method. */ -/***********************************************************************/ -int TDBTBL::WriteDB(PGLOBAL g) - { - strcpy(g->Message, MSG(TABMUL_READONLY)); - return RC_FX; // NIY - } // end of WriteDB - -/***********************************************************************/ -/* Data Base delete line routine for MUL access method. */ -/***********************************************************************/ -int TDBTBL::DeleteDB(PGLOBAL g, int irc) - { - strcpy(g->Message, MSG(TABMUL_READONLY)); - return RC_FX; // NIY - } // end of DeleteDB - -/***********************************************************************/ -/* Data Base close routine for MUL access method. */ -/***********************************************************************/ -void TDBTBL::CloseDB(PGLOBAL g) - { - if (Tdbp) - Tdbp->CloseDB(g); - - } // end of CloseDB - -/* ---------------------------- TBLCOL ------------------------------- */ - -/***********************************************************************/ -/* TBLCOL public constructor. */ -/***********************************************************************/ -TBLCOL::TBLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) - : COLBLK(cdp, tdbp, i) - { - if (cprec) { - Next = cprec->GetNext(); - cprec->SetNext(this); - } else { - Next = tdbp->GetColumns(); - tdbp->SetColumns(this); - } // endif cprec - - // Set additional Dos access method information for column. - Long = cdp->GetLong(); // ??? -//strcpy(F_Date, cdp->F_Date); - Colp = NULL; - To_Val = NULL; - Pseudo = FALSE; - Colnum = cdp->GetOffset(); // If columns are retrieved by number - - if (trace) - htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this); - - } // end of TBLCOL constructor - -#if 0 -/***********************************************************************/ -/* TBLCOL public constructor. */ -/***********************************************************************/ -TBLCOL::TBLCOL(SPCBLK *scp, PTDB tdbp) : COLBLK(scp->GetName(), tdbp, 0) - { - // Set additional TBL access method information for pseudo column. - Is_Key = Was_Key = scp->IsKey(); - Long = scp->GetLength(); - Buf_Type = scp->GetResultType(); - *Format.Type = (Buf_Type == TYPE_INT) ? 'N' : 'C'; - Format.Length = Long; - Colp = NULL; - To_Val = NULL; - Pseudo = TRUE; - } // end of TBLCOL constructor - -/***********************************************************************/ -/* TBLCOL constructor used for copying columns. */ -/* tdbp is the pointer to the new table descriptor. */ -/***********************************************************************/ -TBLCOL::TBLCOL(TBLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp) - { - Long = col1->Long; - Colp = col1->Colp; - To_Val = col1->To_Val; - Pseudo = col1->Pseudo; - } // end of TBLCOL copy constructor -#endif - -/***********************************************************************/ -/* TBLCOL initialization routine. */ -/* Look for the matching column in the current table. */ -/***********************************************************************/ -bool TBLCOL::Init(PGLOBAL g) - { - PTDBTBL tdbp = (PTDBTBL)To_Tdb; - - To_Val = NULL; - - if (!(Colp = tdbp->Tdbp->ColDB(g, Name, 0)) && Colnum) - Colp = tdbp->Tdbp->ColDB(g, NULL, Colnum); - - if (Colp) { - Colp->InitValue(g); // May not have been done elsewhere - To_Val = Colp->GetValue(); - } else if (!tdbp->Accept) { - sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName()); - return TRUE; - } else - Value->Reset(); - - return FALSE; - } // end of Init - -/***********************************************************************/ -/* ReadColumn: */ -/***********************************************************************/ -void TBLCOL::ReadColumn(PGLOBAL g) - { - if (trace) - htrc("TBL ReadColumn: name=%s\n", Name); - - if (Colp) { - Colp->ReadColumn(g); - Value->SetValue_pval(To_Val); - } // endif Colp - - } // end of ReadColumn - -/* ---------------------------- TBTBLK ------------------------------- */ - -/***********************************************************************/ -/* ReadColumn: */ -/***********************************************************************/ -void TBTBLK::ReadColumn(PGLOBAL g) - { - if (trace) - htrc("TBT ReadColumn: name=%s\n", Name); - - Value->SetValue_psz((char*)((PTDBTBL)To_Tdb)->Tdbp->GetName()); - } // end of ReadColumn - -/* ------------------------------------------------------------------- */ +/************* TabTbl C++ Program Source Code File (.CPP) **************/ +/* PROGRAM NAME: TABTBL */ +/* ------------- */ +/* Version 1.3 */ +/* */ +/* COPYRIGHT: */ +/* ---------- */ +/* (C) Copyright to PlugDB Software Development 2008-2012 */ +/* Author: Olivier BERTRAND */ +/* */ +/* 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" +#if defined(WIN32) +#include +#include +#if defined(__BORLANDC__) +#define __MFC_COMPAT__ // To define min/max as macro +#endif +//#include +#else +#if defined(UNIX) +#include +#include +#include +#include +#include +#include "osutil.h" +#else +//#include +#endif +//#include +#endif + +/***********************************************************************/ +/* Include application header files: */ +/***********************************************************************/ +#include "table.h" // MySQL table definitions +#include "global.h" // global declarations +#include "plgdbsem.h" // DB application declarations +#include "reldef.h" // DB definition declares +//#include "filter.h" // FILTER classes dcls +#include "filamtxt.h" +#include "tabcol.h" +#include "tabdos.h" // TDBDOS and DOSCOL class dcls +#include "tabtbl.h" // TDBTBL and TBLCOL classes dcls +#include "ha_connect.h" +#include "mycat.h" // For GetHandler + +extern "C" int trace; + +int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags); + +/* ---------------------------- Class TBLDEF ---------------------------- */ + +/**************************************************************************/ +/* Constructor. */ +/**************************************************************************/ +TBLDEF::TBLDEF(void) + { + To_Tables = NULL; + Ntables = 0; + Pseudo = 3; + } // end of TBLDEF constructor + +/**************************************************************************/ +/* DefineAM: define specific AM block values from XDB file. */ +/**************************************************************************/ +bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) + { + char *tablist, *dbname; + + Desc = "Table list table"; + tablist = Cat->GetStringCatInfo(g, Name, "Tablist", ""); + dbname = Cat->GetStringCatInfo(g, Name, "Database", NULL); + Ntables = 0; + + if (*tablist) { + char *p, *pn, *pdb; + PTBL *ptbl = &To_Tables, tbl; + + for (pdb = tablist; ;) { + if ((p = strchr(pdb, ','))) + *p = 0; + + // Analyze the table name, it has 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 = (PTBL)PlugSubAlloc(g, NULL, sizeof(TBLIST)); + tbl->Next = NULL; + tbl->Name = pn; + tbl->DB = pdb; + + if (trace) + htrc("TBL: Name=%s db=%s\n", tbl->Name, SVP(tbl->DB)); + + // Link the blocks + *ptbl = tbl; + ptbl = &tbl->Next; + Ntables++; + + if (p) + pdb = pn + strlen(pn) + 1; + else + break; + + } // endfor pdb + + Maxerr = Cat->GetIntCatInfo(Name, "Maxerr", 0); + Accept = (Cat->GetBoolCatInfo(Name, "Accept", 0) != 0); + } // endif fsec || tablist + + return FALSE; + } // end of DefineAM + +/***********************************************************************/ +/* GetTable: makes a new Table Description Block. */ +/***********************************************************************/ +PTDB TBLDEF::GetTable(PGLOBAL g, MODE m) + { + PTDB tdbp; + + /*********************************************************************/ + /* Allocate a TDB of the proper type. */ + /* Column blocks will be allocated only when needed. */ + /*********************************************************************/ + tdbp = new(g) TDBTBL(this); + + return tdbp; + } // end of GetTable + +/* ------------------------- Class TDBTBL ---------------------------- */ + +/***********************************************************************/ +/* TDBTBL constructors. */ +/***********************************************************************/ +TDBTBL::TDBTBL(PTBLDEF tdp) : TDBASE(tdp) + { + Tablist = NULL; + CurTable = NULL; + Tdbp = NULL; + Accept = tdp->Accept; + Maxerr = tdp->Maxerr; + Nbf = 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) TBLCOL(cdp, this, cprec, n); + } // end of MakeCol + +/***********************************************************************/ +/* InsertSpecialColumn: Put a special column ahead of the column list.*/ +/***********************************************************************/ +PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, 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 + +/***********************************************************************/ +/* Get the PTDB of a table of the list. */ +/***********************************************************************/ +PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp) + { + char *db, key[128]; + uint k, flags; + PTDB tdbp = NULL; + TABLE_LIST table_list; + TABLE_SHARE *s; + PCATLG cat = To_Def->GetCat(); + PHC hc = ((MYCAT*)cat)->GetHandler(); + THD *thd = (hc->GetTable())->in_use; + + if (!thd) + return NULL; // Should not happen anymore + + if (tblp->DB) + db = tblp->DB; + else + db = (char*)hc->GetDBName(NULL); + + table_list.init_one_table(db, strlen(db), + tblp->Name, strlen(tblp->Name), + NULL, TL_IGNORE); + k = sprintf(key, "%s\0%s\0", db, tblp->Name); + + if (!(s = alloc_table_share(&table_list, key, k))) { + strcpy(g->Message, "Error allocating share\n"); + return NULL; + } // endif s + +// 1 8 16 +//flags = READ_ALL | DONT_OPEN_TABLES | DONT_OPEN_MASTER_REG; +//flags = 25; + flags = 24; + + if (!open_table_def(thd, s, flags)) { + hc->tshp = s; + tdbp = cat->GetTable(g, tabp); + hc->tshp = NULL; + } else + sprintf(g->Message, "Error %d opening share\n", s->error); + + if (trace && tdbp) + htrc("Subtable %s in %s\n", + tblp->Name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB())); + + free_table_share(s); + return tdbp; + } // end of GetSubTable + +/***********************************************************************/ +/* Initializes the table table list. */ +/***********************************************************************/ +bool TDBTBL::InitTableList(PGLOBAL g) + { + char *colname; + int n, colpos; + PTBL tblp; + PTABLE tabp; + PTDB tdbp; + PCOL colp; + PTBLDEF tdp = (PTBLDEF)To_Def; + +// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath()); + + for (n = 0, tblp = tdp->GetTables(); tblp; tblp = tblp->Next) { + if (TestFil(g, To_Filter, tblp)) { + // Table or named view + tabp = new(g) XTAB(tblp->Name); + tabp->SetQualifier(tblp->DB); + + // Get the table description block of this table + if (!(tdbp = GetSubTable(g, tblp, tabp))) { + if (++Nbf > Maxerr) + return TRUE; // Error return + else + continue; // Skip this table + + } // endif tdbp + + // 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 (PCOL cp = Columns; cp; cp = cp->GetNext()) + if (!cp->IsSpecial()) { + colname = cp->GetName(); + colpos = ((PTBLCOL)cp)->Colnum; + + // We try first to get the column by name + if (!(colp = tdbp->ColDB(g, colname, 0)) && colpos) + // When unsuccessful, if a column number was specified + // try to get the column by its position in the table + colp = tdbp->ColDB(g, NULL, colpos); + + if (!colp) { + if (!Accept) { + sprintf(g->Message, MSG(NO_MATCHING_COL), + colname, tdbp->GetName()); + return TRUE; // Error return + } // endif !Accept + + } else // this is needed in particular by PLG tables + colp->SetColUse(cp->GetColUse()); + + } // endif !special + + if (Tablist) + Tablist->Link(tabp); + else + Tablist = tabp; + + n++; + } // endif filp + + } // endfor tblp + +//NumTables = n; + To_Filter = 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, PFIL filp, PTBL tblp) + { + char *fil, op[8], tn[NAME_LEN]; + bool neg; + + if (!filp) + return TRUE; + else if (strstr(filp, " OR ") || strstr(filp, " AND ")) + return TRUE; // Not handled yet + else + fil = filp + (*filp == '(' ? 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, tblp->Name); + } 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, tblp->Name)) + return !neg; // Found + + tnl = p; + } // endwhile + + return neg; // Not found + } // endif op + + return TRUE; // invalid operator + } // end of TestFil + +/***********************************************************************/ +/* TBL GetProgMax: get the max value for progress information. */ +/***********************************************************************/ +int TDBTBL::GetProgMax(PGLOBAL g) + { + PTABLE tblp; + int n, pmx = 0; + + if (!Tablist && InitTableList(g)) + return -1; + + for (tblp = Tablist; tblp; tblp = tblp->GetNext()) + if ((n = tblp->GetTo_Tdb()->GetProgMax(g)) > 0) + pmx += n; + + return pmx; + } // end of GetProgMax + +/***********************************************************************/ +/* TBL GetProgCur: get the current value for progress information. */ +/***********************************************************************/ +int TDBTBL::GetProgCur(void) + { + return Crp + Tdbp->GetProgCur(); + } // end of GetProgCur + +#if 0 +/***********************************************************************/ +/* TBL Cardinality: returns table cardinality in number of rows. */ +/* This function can be called with a null argument to test the */ +/* availability of Cardinality implementation (1 yes, 0 no). */ +/* Can be used on Multiple FIX table only. */ +/***********************************************************************/ +int TDBTBL::Cardinality(PGLOBAL g) + { + if (!g) + return Tdbp->Cardinality(g); + + if (!Tablist && InitTableList(g)) + return -1; + + int n, card = 0; + + for (int i = 0; i < NumFiles; i++) { + Tdbp->SetFile(g, Filenames[i]); + Tdbp->ResetSize(); + + if ((n = Tdbp->Cardinality(g)) < 0) { +// strcpy(g->Message, MSG(BAD_CARDINALITY)); + return -1; + } // endif n + + card += n; + } // endfor i + + return card; + } // end of Cardinality +#endif // 0 + +/***********************************************************************/ +/* Sum up the sizes of all sub-tables. */ +/***********************************************************************/ +int TDBTBL::GetMaxSize(PGLOBAL g) + { + if (MaxSize < 0) { + PTABLE tblp; + int mxsz; + + if (!Tablist && InitTableList(g)) + return 0; // Cannot be calculated at this stage + +// if (Use == USE_OPEN) { +// strcpy(g->Message, MSG(MAXSIZE_ERROR)); +// return -1; +// } else + MaxSize = 0; + + for (tblp = Tablist; tblp; tblp = tblp->GetNext()) { + if ((mxsz = tblp->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->COLBLK::Reset(); + + for (PTABLE tblp = Tablist; tblp; tblp = tblp->GetNext()) + ((PTDBASE)tblp->GetTo_Tdb())->ResetDB(); + + Tdbp = (PTDBASE)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) + 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 + +#if 0 + /*********************************************************************/ + /* Direct access needed for join or sorting. */ + /*********************************************************************/ + if (NeedIndexing(g)) { + // Direct access of TBL tables is not implemented yet + strcpy(g->Message, MSG(NO_MUL_DIR_ACC)); + return TRUE; + } // endif NeedIndexing +#endif // 0 + + /*********************************************************************/ + /* When GetMaxsize was called, To_Filter was not set yet. */ + /*********************************************************************/ + if (To_Filter && Tablist) { + Tablist = NULL; + Nbf = 0; + } // endif To_Filter + + /*********************************************************************/ + /* Open the first table of the list. */ + /*********************************************************************/ + if (!Tablist && InitTableList(g)) // done in GetMaxSize + return TRUE; + + if ((CurTable = Tablist)) { + Tdbp = (PTDBASE)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 (((PTBLCOL)cp)->Init(g)) + return TRUE; + + if (trace) + 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 = (PTDBASE)CurTable->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 (((PTBLCOL)cp)->Init(g)) + return RC_FX; + + if (trace) + 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 + +/***********************************************************************/ +/* Data Base write routine for MUL access method. */ +/***********************************************************************/ +int TDBTBL::WriteDB(PGLOBAL g) + { + strcpy(g->Message, MSG(TABMUL_READONLY)); + return RC_FX; // NIY + } // end of WriteDB + +/***********************************************************************/ +/* Data Base delete line routine for MUL access method. */ +/***********************************************************************/ +int TDBTBL::DeleteDB(PGLOBAL g, int irc) + { + strcpy(g->Message, MSG(TABMUL_READONLY)); + return RC_FX; // NIY + } // end of DeleteDB + +/***********************************************************************/ +/* Data Base close routine for MUL access method. */ +/***********************************************************************/ +void TDBTBL::CloseDB(PGLOBAL g) + { + if (Tdbp) + Tdbp->CloseDB(g); + + } // end of CloseDB + +/* ---------------------------- TBLCOL ------------------------------- */ + +/***********************************************************************/ +/* TBLCOL public constructor. */ +/***********************************************************************/ +TBLCOL::TBLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) + : COLBLK(cdp, tdbp, i) + { + if (cprec) { + Next = cprec->GetNext(); + cprec->SetNext(this); + } else { + Next = tdbp->GetColumns(); + tdbp->SetColumns(this); + } // endif cprec + + // Set additional Dos access method information for column. + Long = cdp->GetLong(); // ??? +//strcpy(F_Date, cdp->F_Date); + Colp = NULL; + To_Val = NULL; + Pseudo = FALSE; + Colnum = cdp->GetOffset(); // If columns are retrieved by number + + if (trace) + htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this); + + } // end of TBLCOL constructor + +#if 0 +/***********************************************************************/ +/* TBLCOL public constructor. */ +/***********************************************************************/ +TBLCOL::TBLCOL(SPCBLK *scp, PTDB tdbp) : COLBLK(scp->GetName(), tdbp, 0) + { + // Set additional TBL access method information for pseudo column. + Is_Key = Was_Key = scp->IsKey(); + Long = scp->GetLength(); + Buf_Type = scp->GetResultType(); + *Format.Type = (Buf_Type == TYPE_INT) ? 'N' : 'C'; + Format.Length = Long; + Colp = NULL; + To_Val = NULL; + Pseudo = TRUE; + } // end of TBLCOL constructor + +/***********************************************************************/ +/* TBLCOL constructor used for copying columns. */ +/* tdbp is the pointer to the new table descriptor. */ +/***********************************************************************/ +TBLCOL::TBLCOL(TBLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp) + { + Long = col1->Long; + Colp = col1->Colp; + To_Val = col1->To_Val; + Pseudo = col1->Pseudo; + } // end of TBLCOL copy constructor +#endif + +/***********************************************************************/ +/* TBLCOL initialization routine. */ +/* Look for the matching column in the current table. */ +/***********************************************************************/ +bool TBLCOL::Init(PGLOBAL g) + { + PTDBTBL tdbp = (PTDBTBL)To_Tdb; + + To_Val = NULL; + + if (!(Colp = tdbp->Tdbp->ColDB(g, Name, 0)) && Colnum) + Colp = tdbp->Tdbp->ColDB(g, NULL, Colnum); + + if (Colp) { + Colp->InitValue(g); // May not have been done elsewhere + To_Val = Colp->GetValue(); + } else if (!tdbp->Accept) { + sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName()); + return TRUE; + } else + Value->Reset(); + + return FALSE; + } // end of Init + +/***********************************************************************/ +/* ReadColumn: */ +/***********************************************************************/ +void TBLCOL::ReadColumn(PGLOBAL g) + { + if (trace) + htrc("TBL ReadColumn: name=%s\n", Name); + + if (Colp) { + Colp->ReadColumn(g); + Value->SetValue_pval(To_Val); + } // endif Colp + + } // end of ReadColumn + +/* ---------------------------- TBTBLK ------------------------------- */ + +/***********************************************************************/ +/* ReadColumn: */ +/***********************************************************************/ +void TBTBLK::ReadColumn(PGLOBAL g) + { + if (trace) + htrc("TBT ReadColumn: name=%s\n", Name); + + Value->SetValue_psz((char*)((PTDBTBL)To_Tdb)->Tdbp->GetName()); + } // end of ReadColumn + +/* ------------------------------------------------------------------- */ -- cgit v1.2.1