summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2014-10-31 12:28:07 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2014-10-31 12:28:07 +0100
commit4a17149ba32a604eabf95c198b00fc4b156f8d5d (patch)
tree24cf8575ba6042de0c23a6a61c391d3889082b6d /storage
parent652b96482789ddee1b01c69559fc0d3840976f88 (diff)
downloadmariadb-git-4a17149ba32a604eabf95c198b00fc4b156f8d5d.tar.gz
- Add new table type VIR and virtual index
modified: storage/connect/connect.cc storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/mycat.cc storage/connect/plgdbsem.h - Get good message when calling ColDB modified: storage/connect/connect.cc - Fix buffer preparation for BIN files modified: storage/connect/filamfix.cpp fix error while updating (force fseek) modified: storage/connect/filamfix.cpp fix error of XCOL column when filtered (typo) modified: storage/connect/tabdos.cpp storage/connect/tabxcl.cpp fix error when indexing on special column modified: storage/connect/tabdos.cpp
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/connect.cc32
-rw-r--r--storage/connect/filamfix.cpp53
-rw-r--r--storage/connect/ha_connect.cc85
-rw-r--r--storage/connect/ha_connect.h1
-rw-r--r--storage/connect/mycat.cc7
-rw-r--r--storage/connect/plgdbsem.h10
-rw-r--r--storage/connect/tabdos.cpp9
-rw-r--r--storage/connect/tabxcl.cpp2
-rw-r--r--storage/connect/tabxcl.h2
9 files changed, 169 insertions, 32 deletions
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index cdbc056fe6f..db47a3e48e8 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -276,16 +276,13 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (trace)
printf("Allocating column %s\n", p);
-// if (*p == '*') {
-// // This is a special column
-// cp= new(g) COLUMN(p + 1);
-// cp->SetTo_Table(tdbp->GetTable());
-// colp= ((PTDBASE)tdbp)->InsertSpcBlk(g, cp);
-// } else
- colp= tdbp->ColDB(g, p, 0);
+ g->Message[0] = 0; // To check whether ColDB made an error message
+ colp= tdbp->ColDB(g, p, 0);
if (!colp && !(mode == MODE_INSERT && tdbp->IsSpecial(p))) {
- sprintf(g->Message, "Column %s not found in %s", p, tdbp->GetName());
+ if (g->Message[0] == 0)
+ sprintf(g->Message, "Column %s not found in %s", p, tdbp->GetName());
+
goto err;
} // endif colp
@@ -656,6 +653,8 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted)
else if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
sprintf(g->Message, "CntIndexInit: Table %s is not indexable", ptdb->GetName());
return 0;
+ } else if (((PTDBASE)ptdb)->GetDef()->Indexable() == 3) {
+ return 1;
} else
tdbp= (PTDBDOX)ptdb;
@@ -733,6 +732,14 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
return RC_FX;
goto rnd;
+ } else if (x == 3) {
+ if (key)
+ ((PTDBASE)ptdb)->SetRecpos(g, *(int*)key);
+
+ if (op == OP_SAME)
+ return RC_NF;
+
+ goto rnd;
} else
tdbp= (PTDBDOX)ptdb;
@@ -837,6 +844,15 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
} else if (x == 2) {
// Remote index
return 2;
+ } else if (x == 3) {
+ // Virtual index
+ for (i= 0; i < 2; i++)
+ if (key[i])
+ k[i] = *(int*)key[i] + (incl[i] ? 0 : 1 - 2 * i);
+ else
+ k[i] = (i) ? ptdb->Cardinality(g) : 1;
+
+ return k[1] - k[0] + 1;
} else
tdbp= (PTDBDOX)ptdb;
diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp
index 0df5e8087ac..980d558eee5 100644
--- a/storage/connect/filamfix.cpp
+++ b/storage/connect/filamfix.cpp
@@ -130,18 +130,49 @@ bool FIXFAM::AllocateBuffer(PGLOBAL g)
/*******************************************************************/
/* For Insert the buffer must be prepared. */
/*******************************************************************/
- memset(To_Buf, ' ', Buflen);
+ if (Tdbp->GetFtype() == RECFM_BIN) {
+ // The buffer must be prepared depending on column types
+ int n = 0;
+ PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
+ PCOLDEF cdp;
- if (/*Tdbp->GetFtype() < 2 &&*/ !Padded)
- // If not binary, the file is physically a text file.
- // We do it also for binary table because the lrecl can have been
+ // Prepare the first line of the buffer
+ memset(To_Buf, 0, Buflen);
+
+ for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext()) {
+ if (IsTypeNum(cdp->GetType()))
+ memset(To_Buf + cdp->GetOffset(), ' ', cdp->GetClen());
+
+ n = MY_MAX(n, cdp->GetPoff() + cdp->GetClen());
+ } // endfor cdp
+
+ // We do this for binary table because the lrecl can have been
// specified with additional space to include line ending.
- for (int len = Lrecl; len <= Buflen; len += Lrecl) {
-#if defined(WIN32)
- To_Buf[len - 2] = '\r';
-#endif // WIN32
- To_Buf[len - 1] = '\n';
- } // endfor len
+ if (n < Lrecl && Ending) {
+ To_Buf[Lrecl - 1] = '\n';
+
+ if (n < Lrecl - 1 && Ending == 2)
+ To_Buf[Lrecl - 2] = '\r';
+
+ } // endif n
+
+ // Now repeat this for the whole buffer
+ for (int len = Lrecl; len <= Buflen - Lrecl; len += Lrecl)
+ memcpy(To_Buf + len, To_Buf, Lrecl);
+
+ } else {
+ memset(To_Buf, ' ', Buflen);
+
+ if (!Padded)
+ // The file is physically a text file.
+ for (int len = Lrecl; len <= Buflen; len += Lrecl) {
+ if (Ending == 2)
+ To_Buf[len - 2] = '\r';
+
+ To_Buf[len - 1] = '\n';
+ } // endfor len
+
+ } // endif Ftype
Rbuf = Nrec; // To be used by WriteDB
} // endif Insert
@@ -204,7 +235,7 @@ int FIXFAM::WriteModifiedBlock(PGLOBAL g)
// NOTE: Next line was added to avoid a very strange fread bug.
// When the fseek is not executed (even the file has the good
// pointer position) the next read can happen anywhere in the file.
- OldBlk = CurBlk; // This will force fseek to be executed
+ OldBlk = -2; // This will force fseek to be executed
Modif = 0;
return rc;
} // end of WriteModifiedBlock
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 5d32b812494..a36ce688f15 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -207,6 +207,7 @@ static my_bool indx_map= 0;
/* Utility functions. */
/***********************************************************************/
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
+PQRYRES VirColumns(PGLOBAL g, char *tab, char *db, bool info);
void PushWarning(PGLOBAL g, THD *thd, int level);
bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
const char *db, char *tab, const char *src, int port);
@@ -763,6 +764,7 @@ const char *ha_connect::index_type(uint inx)
return "XINDEX";
case 2: return "REMOTE";
+ case 3: return "VIRTUAL";
} // endswitch
return "Unknown";
@@ -1404,6 +1406,42 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
return toidx;
} // end of GetIndexInfo
+/****************************************************************************/
+/* Returns the index description structure used to make the index. */
+/****************************************************************************/
+bool ha_connect::CheckVirtualIndex(TABLE_SHARE *s)
+{
+
+ char *rid;
+ KEY kp;
+ Field *fp;
+ PGLOBAL& g= xp->g;
+
+ if (!s)
+ s= table->s;
+
+ for (int n= 0; (unsigned)n < s->keynames.count; n++) {
+ kp= s->key_info[n];
+
+ // Now get index information
+
+ // Get the the key parts info
+ for (int k= 0; (unsigned)k < kp.user_defined_key_parts; k++) {
+ fp= kp.key_part[k].field;
+ rid= (fp->option_struct) ? fp->option_struct->special : NULL;
+
+ if (!rid || (stricmp(rid, "ROWID") && stricmp(rid, "ROWNUM"))) {
+ strcpy(g->Message, "Invalid virtual index");
+ return true;
+ } // endif rowid
+
+ } // endfor k
+
+ } // endfor n
+
+ return false;
+} // end of CheckVirtualIndex
+
bool ha_connect::IsPartitioned(void)
{
if (tshp)
@@ -3725,6 +3763,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
case TAB_PRX:
case TAB_OCCUR:
case TAB_PIVOT:
+ case TAB_VIR:
return false;
} // endswitch type
@@ -4069,6 +4108,14 @@ int ha_connect::external_lock(THD *thd, int lock_type)
rc= 0;
} // endif MakeIndex
+ } else if (((PTDBASE)tdbp)->GetDef()->Indexable() == 3) {
+ if (CheckVirtualIndex(NULL)) {
+ // Make it a warning to avoid crash
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
+ 0, g->Message);
+ rc= 0;
+ } // endif Check
+
} // endif indexable
} // endif Tdbp
@@ -4455,7 +4502,7 @@ static char *encode(PGLOBAL g, const char *cnm)
Return 0 if ok
*/
static bool add_field(String *sql, const char *field_name, int typ,
- int len, int dec, uint tm, const char *rem,
+ int len, int dec, char *key, uint tm, const char *rem,
char *dft, char *xtra, int flag, bool dbf, char v)
{
char var = (len > 255) ? 'V' : v;
@@ -4489,6 +4536,11 @@ static bool add_field(String *sql, const char *field_name, int typ,
else if (v == 'Z')
error|= sql->append(" ZEROFILL");
+ if (key && *key) {
+ error|= sql->append(" ");
+ error|= sql->append(key);
+ } // endif key
+
if (tm)
error|= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info);
@@ -4902,6 +4954,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
strcpy(g->Message, "Missing OEM module or subtype");
break;
+ case TAB_VIR:
+ ok= true;
+ break;
default:
sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
break;
@@ -4920,7 +4975,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
} // endif src
if (ok) {
- char *cnm, *rem, *dft, *xtra;
+ char *cnm, *rem, *dft, *xtra, *key;
int i, len, prec, dec, typ, flg;
// if (cat)
@@ -5005,6 +5060,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
case TAB_PIVOT:
qrp= PivotColumns(g, tab, src, pic, fcl, skc, host, db, user, pwd, port);
break;
+ case TAB_VIR:
+ qrp= VirColumns(g, tab, (char*)db, fnc == FNC_COL);
+ break;
case TAB_OEM:
qrp= OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL);
break;
@@ -5036,7 +5094,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec,
NOT_NULL_FLAG, "", flg, dbf, v);
#else // !NEW_WAY
- if (add_field(&sql, cnm, typ, len, dec, NOT_NULL_FLAG,
+ if (add_field(&sql, cnm, typ, len, dec, NULL, NOT_NULL_FLAG,
NULL, NULL, NULL, flg, dbf, v))
rc= HA_ERR_OUT_OF_MEM;
#endif // !NEW_WAY
@@ -5058,7 +5116,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
typ= len= prec= dec= 0;
tm= NOT_NULL_FLAG;
cnm= (char*)"noname";
- dft= xtra= NULL;
+ dft= xtra= key= NULL;
#if defined(NEW_WAY)
rem= "";
// cs= NULL;
@@ -5110,6 +5168,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
xtra= NULL;
break;
+ case FLD_KEY:
+ if (ttp == TAB_VIR)
+ key= crp->Kdata->GetCharValue(i);
+
+ break;
default:
break; // Ignore
} // endswitch Fld
@@ -5150,7 +5213,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
rc= add_fields(g, thd, &alter_info, cnm, typ, prec, dec,
tm, rem, 0, dbf, v);
#else // !NEW_WAY
- if (add_field(&sql, cnm, typ, prec, dec, tm, rem, dft, xtra,
+ if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
0, dbf, v))
rc= HA_ERR_OUT_OF_MEM;
#endif // !NEW_WAY
@@ -5669,6 +5732,12 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif cat
+ } else if (GetIndexType(type) == 3) {
+ if (CheckVirtualIndex(table_arg->s)) {
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ rc= HA_ERR_UNSUPPORTED;
+ } // endif Check
+
} else if (!GetIndexType(type)) {
sprintf(g->Message, "Table type %s is not indexable", options->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
@@ -5952,6 +6021,12 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
else
DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
+ } else if (GetIndexType(type) == 3) {
+ if (CheckVirtualIndex(altered_table->s)) {
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ DBUG_RETURN(HA_ALTER_ERROR);
+ } // endif Check
+
} else if (!GetIndexType(type)) {
sprintf(g->Message, "Table type %s is not indexable", oldopt->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 2b96e931bb3..6c3ed87d5f6 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -215,6 +215,7 @@ public:
void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
PXOS GetIndexOptionStruct(KEY *kp);
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
+ bool CheckVirtualIndex(TABLE_SHARE *s);
const char *GetDBName(const char *name);
const char *GetTableName(void);
char *GetPartName(void);
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 09a5b7a4dbc..fc6c29092a1 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -88,6 +88,7 @@
#if defined(PIVOT_SUPPORT)
#include "tabpivot.h"
#endif // PIVOT_SUPPORT
+#include "tabvir.h"
#include "ha_connect.h"
#include "mycat.h"
@@ -137,6 +138,7 @@ TABTYPE GetTypeID(const char *type)
#ifdef PIVOT_SUPPORT
: (!stricmp(type, "PIVOT")) ? TAB_PIVOT
#endif
+ : (!stricmp(type, "VIR")) ? TAB_VIR
: (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
} // end of GetTypeID
@@ -180,6 +182,7 @@ bool IsExactType(TABTYPE type)
case TAB_DBF:
// case TAB_XML: depends on Multiple || Xpand || Coltype
case TAB_VEC:
+ case TAB_VIR:
exact= true;
break;
default:
@@ -278,6 +281,9 @@ int GetIndexType(TABTYPE type)
// case TAB_ODBC:
xtyp= 2;
break;
+ case TAB_VIR:
+ xtyp= 3;
+ break;
case TAB_ODBC:
default:
xtyp= 0;
@@ -531,6 +537,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
#if defined(PIVOT_SUPPORT)
case TAB_PIVOT: tdp= new(g) PIVOTDEF; break;
#endif // PIVOT_SUPPORT
+ case TAB_VIR: tdp= new(g) VIRDEF; break;
default:
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
} // endswitch
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index ef209a9b8b8..bbbbc1486b6 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -72,10 +72,11 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
TAB_OCCUR = 18, /* OCCUR table */
TAB_PRX = 19, /* Proxy (catalog) table */
TAB_PLG = 20, /* PLG NIY */
- TAB_PIVOT = 21, /* PIVOT NIY */
- TAB_JCT = 22, /* Junction tables NIY */
- TAB_DMY = 23, /* DMY Dummy tables NIY */
- TAB_NIY = 24}; /* Table not implemented yet */
+ TAB_PIVOT = 21, /* PIVOT table */
+ TAB_VIR = 22, /* Virtual tables */
+ TAB_JCT = 23, /* Junction tables NIY */
+ TAB_DMY = 24, /* DMY Dummy tables NIY */
+ TAB_NIY = 25}; /* Table not implemented yet */
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_ROWID = 1, /* ROWID type (special column) */
@@ -127,6 +128,7 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_TFC = 155, /* TFC (Circa) (Fuzzy compare) */
TYPE_AM_DBF = 160, /* DBF Dbase files am type no */
TYPE_AM_JCT = 170, /* Junction tables am type no */
+ TYPE_AM_VIR = 171, /* Virtual tables am type no */
TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */
TYPE_AM_SET = 180, /* SET Set tables am type no */
TYPE_AM_MYSQL = 192, /* MYSQL access method type no */
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index d9bb17043d9..0ef9625ac9b 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -1778,8 +1778,13 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp, bool sorted)
To_Link = (PXOB*)PlugSubAlloc(g, NULL, Knum * sizeof(PXOB));
for (k = 0, kdp = xdp->GetToKeyParts(); kdp; k++, kdp = kdp->GetNext()) {
- cdp = Key(k)->GetCdp();
- valp = AllocateValue(g, cdp->GetType(), cdp->GetLength());
+ if ((cdp = Key(k)->GetCdp()))
+ valp = AllocateValue(g, cdp->GetType(), cdp->GetLength());
+ else { // Special column ?
+ colp = Key(k);
+ valp = AllocateValue(g, colp->GetResultType(), colp->GetLength());
+ } // endif cdp
+
To_Link[k]= new(g) CONSTANT(valp);
} // endfor k
diff --git a/storage/connect/tabxcl.cpp b/storage/connect/tabxcl.cpp
index 8148723c6be..57f0e1e03b9 100644
--- a/storage/connect/tabxcl.cpp
+++ b/storage/connect/tabxcl.cpp
@@ -266,7 +266,7 @@ bool XCLCOL::Init(PGLOBAL g, PTDBASE tp)
void XCLCOL::ReadColumn(PGLOBAL g)
{
if (((PTDBXCL)To_Tdb)->New) {
- Colp->Reset(); // In case of failed filtering
+ Colp->Reset(); // Moved here in case of failed filtering
Colp->Eval(g);
strncpy(Cbuf, To_Val->GetCharValue(), Colp->GetLength());
Cbuf[Colp->GetLength()] = 0;
diff --git a/storage/connect/tabxcl.h b/storage/connect/tabxcl.h
index 05118c5dd25..7e11600c090 100644
--- a/storage/connect/tabxcl.h
+++ b/storage/connect/tabxcl.h
@@ -88,7 +88,7 @@ class XCLCOL : public PRXCOL {
XCLCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
// Methods
- virtual void Reset(void) {Colp->Reset();} // Evaluated only by TDBXCL
+ virtual void Reset(void) {} // Evaluated only by TDBXCL
virtual void ReadColumn(PGLOBAL g);
virtual bool Init(PGLOBAL g, PTDBASE tp = NULL);