mirror of
https://github.com/MariaDB/server.git
synced 2026-04-19 14:55:32 +02:00
- 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
This commit is contained in:
parent
652b964827
commit
4a17149ba3
9 changed files with 169 additions and 32 deletions
|
|
@ -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;
|
||||
|
||||
|
|
@ -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,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
|
||||
|
|
|
|||
|
|
@ -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 @@ 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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue