summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2014-10-31 12:43:55 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2014-10-31 12:43:55 +0100
commit160708e14c873c0cc0026ef94dbd49af92097ffa (patch)
tree2490d7dbc156f92eeead09dfa3bbfb16be04c6d0 /storage
parent4a17149ba32a604eabf95c198b00fc4b156f8d5d (diff)
downloadmariadb-git-160708e14c873c0cc0026ef94dbd49af92097ffa.tar.gz
- Adding the VIR table type implementation files
added: storage/connect/tabvir.cpp storage/connect/tabvir.h
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/tabvir.cpp305
-rw-r--r--storage/connect/tabvir.h105
2 files changed, 410 insertions, 0 deletions
diff --git a/storage/connect/tabvir.cpp b/storage/connect/tabvir.cpp
new file mode 100644
index 00000000000..b4c76f5ad56
--- /dev/null
+++ b/storage/connect/tabvir.cpp
@@ -0,0 +1,305 @@
+/************* 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 -------------------------- */
diff --git a/storage/connect/tabvir.h b/storage/connect/tabvir.h
new file mode 100644
index 00000000000..e781ebc6304
--- /dev/null
+++ b/storage/connect/tabvir.h
@@ -0,0 +1,105 @@
+/**************** 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