Commit 160708e1 authored by Olivier Bertrand's avatar Olivier Bertrand

- Adding the VIR table type implementation files

added:
  storage/connect/tabvir.cpp
  storage/connect/tabvir.h
parent 4a17149b
/************* tdbvir C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: tdbvir.cpp Version 1.1 */
/* (C) Copyright to the author Olivier BERTRAND 2014 */
/* This program are the VIR classes DB execution routines. */
/***********************************************************************/
/***********************************************************************/
/* Include relevant sections of the MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* xtable.h is header containing the TDBASE declarations. */
/* tdbvir.h is header containing the VIR classes declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "filter.h"
#include "xtable.h"
#include "reldef.h"
#include "colblk.h"
#include "mycat.h" // for FNC_COL
#include "tabvir.h"
#include "resource.h" // for IDS_COLUMNS
/***********************************************************************/
/* Return the unique column definition to MariaDB. */
/***********************************************************************/
PQRYRES VirColumns(PGLOBAL g, char *tab, char *db, bool info)
{
int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_STRING, TYPE_STRING};
XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME,
FLD_PREC, FLD_KEY, FLD_EXTRA};
unsigned int length[] = {8, 4, 16, 4, 16, 16};
int i, n, ncol = sizeof(buftyp) / sizeof(int);
PQRYRES qrp;
PCOLRES crp;
n = (info) ? 0 : 1;
/**********************************************************************/
/* Allocate the structures used to refer to the result set. */
/**********************************************************************/
if (!(qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, false, true)))
return NULL;
// Some columns must be renamed before info
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
switch (++i) {
case 5: crp->Name = "Key"; break;
case 6: crp->Name = "Extra"; break;
} // endswitch i
if (info)
return qrp;
/**********************************************************************/
/* Now get the results into blocks. */
/**********************************************************************/
// Set column name
crp = qrp->Colresp; // Column_Name
crp->Kdata->SetValue("n", 0);
// Set type, type name, precision
crp = crp->Next; // Data_Type
crp->Kdata->SetValue(TYPE_INT, 0);
crp = crp->Next; // Type_Name
crp->Kdata->SetValue(GetTypeName(TYPE_INT), 0);
crp = crp->Next; // Precision
crp->Kdata->SetValue(11, 0);
crp = crp->Next; // Key
crp->Kdata->SetValue("KEY", 0);
crp = crp->Next; // Extra
crp->Kdata->SetValue("SPECIAL=ROWID", 0);
qrp->Nblin = 1;
/**********************************************************************/
/* Return the result pointer for use by discovery routines. */
/**********************************************************************/
return qrp;
} // end of VirColumns
/* --------------------------- Class VIRDEF --------------------------- */
/***********************************************************************/
/* GetTable: makes a new Table Description Block. */
/***********************************************************************/
PTDB VIRDEF::GetTable(PGLOBAL g, MODE m)
{
// Column blocks will be allocated only when needed.
if (Catfunc == FNC_COL)
return new(g) TDBVICL(this);
else
return new(g) TDBVIR(this);
} // end of GetTable
/* ------------------------ TDBVIR functions ------------------------- */
/***********************************************************************/
/* Implementation of the TDBVIR class. */
/***********************************************************************/
TDBVIR::TDBVIR(PVIRDEF tdp) : TDBASE(tdp)
{
Size = (tdp->GetElemt()) ? tdp->GetElemt() : 1;
N = -1;
} // end of TDBVIR constructor
/***********************************************************************/
/* Analyze the filter and reset the size limit accordingly. */
/* This is possible when a filter contains predicates implying the */
/* special column ROWID. Here we just test for when no more good */
/* records can be met in the remaining of the table. */
/***********************************************************************/
int TDBVIR::TestFilter(PFIL filp, bool nop)
{
int i, op = filp->GetOpc(), n = 0, type[2] = {0,0};
int l1 = 0, l2, limit = Size;
PXOB arg[2] = {NULL,NULL};
if (op == OP_GT || op == OP_GE || op == OP_LT || op == OP_LE) {
for (i = 0; i < 2; i++) {
arg[i] = filp->Arg(i);
switch (filp->GetArgType(i)) {
case TYPE_CONST:
if ((l1 = arg[i]->GetIntValue()) >= 0)
type[i] = 1;
break;
case TYPE_COLBLK:
if (((PCOL)arg[i])->GetTo_Tdb() == this &&
((PCOL)arg[i])->GetAmType() == TYPE_AM_ROWID)
type[i] = 2;
break;
default:
break;
} // endswitch ArgType
if (!type[i])
break;
n += type[i];
} // endfor i
if (n == 3) {
// If true it will be ok to delete the filter
BOOL ok = (filp == To_Filter);
if (type[0] == 1)
// Make it always a Column-op-Value
switch (op) {
case OP_GT: op = OP_LT; break;
case OP_GE: op = OP_LE; break;
case OP_LT: op = OP_GT; break;
case OP_LE: op = OP_GE; break;
} // endswitch op
if (!nop) switch (op) {
case OP_LT: l1--;
case OP_LE: limit = l1; break;
default: ok = false;
} // endswitch op
else switch (op) {
case OP_GE: l1--;
case OP_GT: limit = l1; break;
default: ok = false;
} // endswitch op
limit = MY_MIN(MY_MAX(0, limit), Size);
// Just one where clause such as Rowid < limit;
if (ok)
To_Filter = NULL;
} else
limit = Size;
} else if ((op == OP_AND && !nop) || (op == OP_OR && nop)) {
l1 = TestFilter((PFIL)filp->Arg(0), nop);
l2 = TestFilter((PFIL)filp->Arg(1), nop);
limit = MY_MIN(l1, l2);
} else if (op == OP_NOT)
limit = TestFilter((PFIL)filp->Arg(0), !nop);
return limit;
} // end of TestFilter
/***********************************************************************/
/* Allocate source column description block. */
/***********************************************************************/
PCOL TDBVIR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
PCOL colp = NULL;
if (cdp->IsVirtual()) {
colp = new(g) VIRCOL(cdp, this, cprec, n);
} else strcpy(g->Message,
"Virtual tables accept only special or virtual columns");
return colp;
} // end of MakeCol
/***********************************************************************/
/* VIR Access Method opening routine. */
/***********************************************************************/
bool TDBVIR::OpenDB(PGLOBAL g)
{
if (Use == USE_OPEN) {
// Table already open
N = -1;
return false;
} // endif use
if (Mode != MODE_READ) {
strcpy(g->Message, "Virtual tables are read only");
return true;
} // endif Mode
/*********************************************************************/
/* Analyze the filter and refine Size accordingly. */
/*********************************************************************/
if (To_Filter)
Size = TestFilter(To_Filter, false);
return false;
} // end of OpenDB
/***********************************************************************/
/* Data Base read routine for the VIR access method. */
/***********************************************************************/
int TDBVIR::ReadDB(PGLOBAL g)
{
return (++N >= Size) ? RC_EF : RC_OK;
} // end of ReadDB
/***********************************************************************/
/* WriteDB: Data Base write routine for the VIR access methods. */
/***********************************************************************/
int TDBVIR::WriteDB(PGLOBAL g)
{
sprintf(g->Message, MSG(VIR_READ_ONLY), To_Def->GetType());
return RC_FX;
} // end of WriteDB
/***********************************************************************/
/* Data Base delete line routine for the VIR access methods. */
/***********************************************************************/
int TDBVIR::DeleteDB(PGLOBAL g, int irc)
{
sprintf(g->Message, MSG(VIR_NO_DELETE), To_Def->GetType());
return RC_FX;
} // end of DeleteDB
/* ---------------------------- VIRCOL ------------------------------- */
/***********************************************************************/
/* VIRCOL public constructor. */
/***********************************************************************/
VIRCOL::VIRCOL(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
} // end of VIRCOL constructor
/***********************************************************************/
/* ReadColumn: */
/***********************************************************************/
void VIRCOL::ReadColumn(PGLOBAL g)
{
// This should never be called
sprintf(g->Message, "ReadColumn: Column %s is not virtual", Name);
longjmp(g->jumper[g->jump_level], TYPE_COLBLK);
} // end of ReadColumn
/* ---------------------------TDBVICL class -------------------------- */
/***********************************************************************/
/* GetResult: Get the list the VIRTUAL table columns. */
/***********************************************************************/
PQRYRES TDBVICL::GetResult(PGLOBAL g)
{
return VirColumns(g, NULL, NULL, false);
} // end of GetResult
/* ------------------------- End of Virtual -------------------------- */
/**************** tdbvir H Declares Source Code File (.H) **************/
/* Name: TDBVIR.H Version 1.1 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2006-2014 */
/* */
/* This file contains the VIR classes declare code. */
/***********************************************************************/
typedef class VIRDEF *PVIRDEF;
typedef class TDBVIR *PTDBVIR;
/* --------------------------- VIR classes --------------------------- */
/***********************************************************************/
/* VIR: Virtual table used to select constant values. */
/***********************************************************************/
class DllExport VIRDEF : public TABDEF { /* Logical table description */
public:
// Constructor
VIRDEF(void) {}
// Implementation
virtual const char *GetType(void) {return "VIRTUAL";}
// Methods
virtual bool DefineAM(PGLOBAL, LPCSTR, int) {Pseudo = 3; return false;}
virtual int Indexable(void) {return 3;}
virtual PTDB GetTable(PGLOBAL g, MODE m);
protected:
// Members
}; // end of VIRDEF
/***********************************************************************/
/* This is the class declaration for the Virtual table. */
/***********************************************************************/
class DllExport TDBVIR : public TDBASE {
public:
// Constructors
TDBVIR(PVIRDEF tdp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_VIR;}
// Methods
virtual int GetRecpos(void) {return N;}
virtual bool SetRecpos(PGLOBAL g, int recpos)
{N = recpos - 2; return false;}
virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;}
int TestFilter(PFIL filp, bool nop);
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int Cardinality(PGLOBAL g) {return (g) ? Size : 1;}
virtual int GetMaxSize(PGLOBAL g) {return Size;}
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g) {}
protected:
// Members
int Size; // Table size
int N; // The VIR table current position
}; // end of class TDBVIR
/***********************************************************************/
/* Class VIRCOL: VIRTUAL access method column descriptor. */
/***********************************************************************/
class VIRCOL : public COLBLK {
friend class TDBVIR;
public:
// Constructors
VIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "VIRTUAL");
// Implementation
virtual int GetAmType(void) {return TYPE_AM_VIR;}
// Methods
virtual void ReadColumn(PGLOBAL g);
protected:
// Default constructor not to be used
VIRCOL(void) {}
// No additional members
}; // end of class VIRCOL
/***********************************************************************/
/* This is the class declaration for the VIR column catalog table. */
/***********************************************************************/
class TDBVICL : public TDBCAT {
public:
// Constructor
TDBVICL(PVIRDEF tdp) : TDBCAT(tdp) {}
// Methods
virtual int Cardinality(PGLOBAL g) {return 2;} // Avoid DBUG_ASSERT
protected:
// Specific routines
virtual PQRYRES GetResult(PGLOBAL g);
// Members
}; // end of class TDBVICL
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment