Commit 4a17149b authored by Olivier Bertrand's avatar Olivier Bertrand

- 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
parent 652b9648
......@@ -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
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))) {
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;
......@@ -732,6 +731,14 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
if (ptdb->ReadKey(g, op, key, len))
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;
......
......@@ -130,19 +130,50 @@ 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;
// 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
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
// We do this for binary table because the lrecl can have been
// specified with additional space to include line ending.
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 defined(WIN32)
if (Ending == 2)
To_Buf[len - 2] = '\r';
#endif // WIN32
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
......
......@@ -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);
......@@ -4901,6 +4953,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
else
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);
......@@ -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;
......@@ -5109,6 +5167,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (!stricmp(xtra, "AUTO_INCREMENT"))
xtra= NULL;
break;
case FLD_KEY:
if (ttp == TAB_VIR)
key= crp->Kdata->GetCharValue(i);
break;
default:
break; // Ignore
......@@ -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));
......
......@@ -215,6 +215,7 @@ class ha_connect: public handler
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);
......
......@@ -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
......
......@@ -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 */
......
......@@ -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();
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
......
......@@ -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;
......
......@@ -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);
......
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