/***********************************************************************/ /* Include application header files: */ /***********************************************************************/ #include"table.h"// MySQL table definitions #include"global.h" #include"plgdbsem.h" #include"plgcnx.h"// For DB types #include"myutil.h" #include"valblk.h" #include"resource.h" //#include "reldef.h" #include"xtable.h" #include"tabext.h" #include"tabmysql.h" #include"tabcol.h" #include"tabutil.h" #include"ha_connect.h"
int GetConvSize(void);
/************************************************************************/ /* Used by MYSQL tables to get MySQL parameters from the calling proxy */ /* table (PROXY, TBL, XCL, or OCCUR) when used by one of these. */ /************************************************************************/
TABLE_SHARE *Remove_tshp(PCATLG cat)
{
TABLE_SHARE *s = ((MYCAT*)cat)->GetHandler()->tshp;
((MYCAT*)cat)->GetHandler()->tshp = NULL; return s;
} // end of Remove_thsp
/************************************************************************/ /* Used by MYSQL tables to get MySQL parameters from the calling proxy */ /* table (PROXY, TBL, XCL, or OCCUR) when used by one of these. */ /************************************************************************/ void Restore_tshp(PCATLG cat, TABLE_SHARE *s)
{
((MYCAT*)cat)->GetHandler()->tshp = s;
} // end of Restore_thsp
/************************************************************************/ /* GetTableShare: allocates and open a table share. */ /************************************************************************/
TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, constchar *db, constchar *name, bool& mysql)
{ char key[256];
uint k;
TABLE_SHARE *s;
if (!(s = alloc_table_share(db, name, key, ++k))) {
strcpy(g->Message, "Error allocating share"); return NULL;
} // endif s
if (!open_table_def(thd, s, GTS_TABLE | GTS_VIEW)) { if (!s->is_view) { if (stricmp(plugin_name(s->db_plugin)->str, "connect"))
mysql = true; else
mysql = false;
} else
mysql = true;
} else { if (thd->is_error())
thd->clear_error(); // Avoid stopping info commands
/************************************************************************/ /* TabColumns: constructs the result blocks containing all the columns */ /* description of the object table that will be retrieved by discovery.*/ /************************************************************************/
PQRYRES TabColumns(PGLOBAL g, THD *thd, constchar *db, constchar *name, bool& info)
{ int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT,
TYPE_STRING, TYPE_STRING, TYPE_STRING};
XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET}; unsignedint length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
PCSZ fmt; char *pn, *tn, *fld, *colname, v; // *chset int i, n, ncol = sizeof(buftyp) / sizeof(int); int prec, len, type, scale; int zconv = GetConvSize(); bool mysql;
TABLE_SHARE *s = NULL;
Field* *field;
Field *fp;
PQRYRES qrp;
PCOLRES crp;
if (!info) { // Analyze the table name, it may have the format: [dbname.]tabname if (strchr((char*)name, '.')) {
tn = (char*)PlugDup(g, name);
pn = strchr(tn, '.');
*pn++ = 0;
db = tn;
name = pn;
} // endif pn
if (!(s = GetTableShare(g, thd, db, name, mysql))) { return NULL;
} elseif (s->is_view) {
strcpy(g->Message, "Use MYSQL type to see columns from a view");
info = true; // To tell caller name is a view
free_table_share(s); return NULL;
} else
n = s->fieldnames.count;
} else {
n = 0;
length[0] = 128;
} // endif info
/**********************************************************************/ /* 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 for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) switch (++i) { case2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break; case10: crp->Name = "Date_fmt"; break; case11: crp->Name = "Collation"; break;
} // endswitch i
if (info) return qrp;
/**********************************************************************/ /* Now get the results into blocks. */ /**********************************************************************/ for (i = 0, field= s->field; *field; field++) {
fp= *field;
// Get column name
crp = qrp->Colresp; // Column_Name
colname = (char *)fp->field_name.str;
crp->Kdata->SetValue(colname, i);
// chset = (char *)fp->charset()->name; // v = (!strcmp(chset, "binary")) ? 'B' : 0;
v = 0;
if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) { if (v == 'K') { // Skip this column
snprintf(g->Message, sizeof(g->Message), "Column %s skipped (unsupported type)", colname);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, g->Message); continue;
} // endif v
if (v == 'X') {
len = zconv;
snprintf(g->Message, sizeof(g->Message), "Column %s converted to varchar(%d)",
colname, len);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, g->Message);
} // endif v
if (fp->flags & ZEROFILL_FLAG)
crp->Nulls[i] = 'Z'; elseif (fp->flags & UNSIGNED_FLAG)
crp->Nulls[i] = 'U'; else// X means TEXT field
crp->Nulls[i] = (v == 'X') ? 'V' : v;
if (type == TYPE_DATE) { // When creating tables we do need info about date columns if (mysql) {
fmt = MyDateFmt(fp->type());
prec = len = strlen(fmt);
} else {
fmt = (PCSZ)fp->option_struct->dateformat;
prec = len = fp->field_length;
} // endif mysql
// Add this item
qrp->Nblin++;
i++; // Can be skipped
} // endfor field
/**********************************************************************/ /* Return the result pointer for use by GetData routines. */ /**********************************************************************/ if (s)
free_table_share(s);
return qrp;
} // end of TabColumns
/* -------------- Implementation of the PROXY classes ---------------- */
/***********************************************************************/ /* PRXDEF constructor. */ /***********************************************************************/
PRXDEF::PRXDEF(void)
{
Tablep = NULL;
Pseudo = 3;
} // end of PRXDEF constructor
/***********************************************************************/ /* DefineAM: define specific AM block values from XCOL file. */ /***********************************************************************/ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR, int)
{ char *pn, *db, *tab, *def = NULL;
db = GetStringCatInfo(g, "Dbname", "*");
def = GetStringCatInfo(g, "Srcdef", NULL);
} else // Analyze the table name, it may have the format: [dbname.]tabname if ((pn = strchr(tab, '.'))) {
*pn++ = 0;
db = tab;
tab = pn;
} // endif pn
Tablep = new(g) XTAB(tab, def);
Tablep->SetSchema(db); returnfalse;
} // end of DefineAM
/***********************************************************************/ /* GetTable: makes a new TDB of the proper type. */ /***********************************************************************/
PTDB PRXDEF::GetTable(PGLOBAL g, MODE)
{ if (Catfunc == FNC_COL) returnnew(g) TDBTBC(this); else returnnew(g) TDBPRX(this);
if (db)
((PTDBMY)tdbp)->SetDatabase(tabp->GetSchema());
if (Mode == MODE_UPDATE || Mode == MODE_DELETE)
tdbp->SetName(Name); // For Make_Command
} else { // Sub-table is a CONNECT table
tabp->Next = To_Table; // For loop checking
tdbp = cat->GetTable(g, tabp, Mode);
} // endif mysql
if (s) { if (s->is_view && !b)
s->field = NULL;
hc->tshp = NULL;
} elseif (b) { // Restore s structure that can be in cache
hc->get_table()->field = fp;
hc->get_table()->s->option_struct_table->srcdef = sp;
} // endif s
if (trace(1) && tdbp)
htrc("Subtable %s in %s\n",
name, SVP(tdbp->GetDef()->GetDB()));
err: if (s)
free_table_share(s);
return tdbp;
} // end of GetSubTable
/***********************************************************************/ /* Initializes the table. */ /***********************************************************************/ bool TDBPRX::InitTable(PGLOBAL g)
{ if (!Tdbp) { // Get the table description block of this table if (!(Tdbp = GetSubTable(g, ((PPRXDEF)To_Def)->Tablep))) returntrue;
// Tdbp->SetMode(Mode);
} // endif Tdbp
returnfalse;
} // end of InitTable
/***********************************************************************/ /* Allocate PRX column description block. */ /***********************************************************************/
PCOL TDBPRX::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{ returnnew(g) PRXCOL(cdp, this, cprec, n);
} // end of MakeCol
/***********************************************************************/ /* PRX Cardinality: returns the number of rows in the table. */ /***********************************************************************/ int TDBPRX::Cardinality(PGLOBAL g)
{ if (Cardinal < 0) { if (InitTable(g)) return0;
/***********************************************************************/ /* PRX GetMaxSize: returns the maximum number of rows in the table. */ /***********************************************************************/ int TDBPRX::GetMaxSize(PGLOBAL g)
{ if (MaxSize < 0) { if (InitTable(g)) return0;
MaxSize = Tdbp->GetMaxSize(g);
} // endif MaxSize
return MaxSize;
} // end of GetMaxSize
/***********************************************************************/ /* In this sample, ROWID will be the (virtual) row number, */ /* while ROWNUM will be the occurrence rank in the multiple column. */ /***********************************************************************/ int TDBPRX::RowNumber(PGLOBAL g, bool b)
{ return Tdbp->RowNumber(g, b);
} // end of RowNumber
/***********************************************************************/ /* PROXY Access Method opening routine. */ /***********************************************************************/ bool TDBPRX::OpenDB(PGLOBAL g)
{ if (Use == USE_OPEN) { /*******************************************************************/ /* Table already open, just replace it at its beginning. */ /*******************************************************************/ return Tdbp->OpenDB(g);
} // endif use
if (InitTable(g)) returntrue; elseif (Mode != MODE_READ && (Read_Only || Tdbp->IsReadOnly())) {
strcpy(g->Message, "Cannot modify a read only table"); returntrue;
} // endif tp
/*********************************************************************/ /* Check and initialize the subtable columns. */ /*********************************************************************/ for (PCOL cp = Columns; cp; cp = cp->GetNext()) if (((PPRXCOL)cp)->Init(g, Tdbp)) returntrue;
/*********************************************************************/ /* In Update mode, the updated column blocks must be distinct from */ /* the read column blocks. So make a copy of the TDB and allocate */ /* its column blocks in mode write (required by XML tables). */ /*********************************************************************/ if (Mode == MODE_UPDATE) {
PTDB utp;
/*********************************************************************/ /* Physically open the object table. */ /*********************************************************************/ if (Tdbp->OpenDB(g)) returntrue;
Tdbp->SetNext(NULL);
Use = USE_OPEN; returnfalse;
} // end of OpenDB
/***********************************************************************/ /* Data Base read routine for PROY access method. */ /***********************************************************************/ int TDBPRX::ReadDB(PGLOBAL g)
{ /*********************************************************************/ /* Now start the reading process. */ /*********************************************************************/ return Tdbp->ReadDB(g);
} // end of ReadDB
/***********************************************************************/ /* WriteDB: Data Base write routine for PROXY access methods. */ /***********************************************************************/ int TDBPRX::WriteDB(PGLOBAL g)
{ return Tdbp->WriteDB(g);
} // end of WriteDB
/***********************************************************************/ /* Data Base delete line routine for PROXY access methods. */ /***********************************************************************/ int TDBPRX::DeleteDB(PGLOBAL g, int irc)
{ return Tdbp->DeleteDB(g, irc);
} // end of DeleteDB
/***********************************************************************/ /* Used by the TBL tables. */ /***********************************************************************/ void TDBPRX::RemoveNext(PTABLE tp)
{
tp->Next = NULL;
} // end of RemoveNext
/***********************************************************************/ /* PRXCOL public constructor. */ /***********************************************************************/
PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: COLBLK(cdp, tdbp, i)
{ if (cprec) {
Next = cprec->GetNext();
cprec->SetNext(this);
} else {
Next = tdbp->GetColumns();
tdbp->SetColumns(this);
} // endif cprec
// Set additional Dos access method information for column. Long = cdp->GetLong(); // Useful ??? //strcpy(F_Date, cdp->F_Date);
Colp = NULL;
To_Val = NULL;
Pseudo = false;
Colnum = cdp->GetOffset(); // If columns are retrieved by number
if (trace(1))
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
} // end of PRXCOL constructor
/***********************************************************************/ /* PRXCOL constructor used for copying columns. */ /* tdbp is the pointer to the new table descriptor. */ /***********************************************************************/
PRXCOL::PRXCOL(PRXCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
{
Colp = col1->Colp;
To_Val = col1->To_Val;
Pseudo = col1->Pseudo;
Colnum = col1->Colnum;
} // end of PRXCOL copy constructor
/***********************************************************************/ /* Convert an UTF-8 name to latin characters. */ /***********************************************************************/ char *PRXCOL::Decode(PGLOBAL g, constchar *cnm)
{ char *buf= (char*)PlugSubAlloc(g, NULL, strlen(cnm) + 1);
uint dummy_errors;
uint32 len= copy_and_convert(buf, strlen(cnm) + 1,
&my_charset_latin1,
cnm, strlen(cnm),
&my_charset_utf8mb3_general_ci,
&dummy_errors);
buf[len]= '\0'; return buf;
} // end of Decode
/***********************************************************************/ /* PRXCOL initialization routine. */ /* Look for the matching column in the object table. */ /***********************************************************************/ bool PRXCOL::Init(PGLOBAL g, PTDB tp)
{ if (!tp)
tp = ((PTDBPRX)To_Tdb)->Tdbp;
// Needed for MYSQL subtables
((COLBLK*)Colp)->SetName(Decode(g, Colp->GetName()));
// May not have been done elsewhere
Colp->InitValue(g);
To_Val = Colp->GetValue();
if (mode == MODE_INSERT || mode == MODE_UPDATE) if (Colp->SetBuffer(g, Colp->GetValue(), true, false)) returntrue;
// this may be needed by some tables (which?)
Colp->SetColUse(ColUse);
} else {
snprintf(g->Message, sizeof(g->Message), MSG(NO_MATCHING_COL), Name, tp->GetName()); returntrue;
} // endif Colp
returnfalse;
} // end of Init
/***********************************************************************/ /* Reset the column descriptor to non evaluated yet. */ /***********************************************************************/ void PRXCOL::Reset(void)
{ if (Colp)
Colp->Reset();
if (Colp) {
To_Val->SetValue_pval(Value);
Colp->WriteColumn(g);
} // endif Colp
} // end of WriteColumn
/* ---------------------------TDBTBC class --------------------------- */
/***********************************************************************/ /* TDBTBC class constructor. */ /***********************************************************************/
TDBTBC::TDBTBC(PPRXDEF tdp) : TDBCAT(tdp)
{
Db = (PSZ)tdp->Tablep->GetSchema();
Tab = (PSZ)tdp->Tablep->GetName();
} // end of TDBTBC constructor
/***********************************************************************/ /* GetResult: Get the list the MYSQL table columns. */ /***********************************************************************/
PQRYRES TDBTBC::GetResult(PGLOBAL g)
{ bool b = false;
return TabColumns(g, current_thd, Db, Tab, b);
} // end of GetResult
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.