diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2014-10-31 12:28:07 +0100 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2014-10-31 12:28:07 +0100 |
commit | 4a17149ba32a604eabf95c198b00fc4b156f8d5d (patch) | |
tree | 24cf8575ba6042de0c23a6a61c391d3889082b6d /storage | |
parent | 652b96482789ddee1b01c69559fc0d3840976f88 (diff) | |
download | mariadb-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.cc | 32 | ||||
-rw-r--r-- | storage/connect/filamfix.cpp | 53 | ||||
-rw-r--r-- | storage/connect/ha_connect.cc | 85 | ||||
-rw-r--r-- | storage/connect/ha_connect.h | 1 | ||||
-rw-r--r-- | storage/connect/mycat.cc | 7 | ||||
-rw-r--r-- | storage/connect/plgdbsem.h | 10 | ||||
-rw-r--r-- | storage/connect/tabdos.cpp | 9 | ||||
-rw-r--r-- | storage/connect/tabxcl.cpp | 2 | ||||
-rw-r--r-- | storage/connect/tabxcl.h | 2 |
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); |