mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- Implement "remote" index (similar to FEDERATED ones) for MYSQL tables.
Not yet done for ODBC tables. modified: storage/connect/connect.cc storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/mycat.cc storage/connect/plgdbsem.h storage/connect/reldef.h storage/connect/tabdos.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/xindex.cpp storage/connect/xtable.h - Return error in "info" on Cardinality error. modified: storage/connect/ha_connect.cc
This commit is contained in:
@@ -587,7 +587,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
|
|||||||
tbxp= (TDBDOX*)tdbp;
|
tbxp= (TDBDOX*)tdbp;
|
||||||
tbxp->SetKindex(NULL);
|
tbxp->SetKindex(NULL);
|
||||||
tbxp->To_Key_Col= NULL;
|
tbxp->To_Key_Col= NULL;
|
||||||
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable());
|
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (trace > 1)
|
if (trace > 1)
|
||||||
@@ -709,7 +709,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
|
|||||||
const void *key, int len)
|
const void *key, int len)
|
||||||
{
|
{
|
||||||
char *kp= (char*)key;
|
char *kp= (char*)key;
|
||||||
int n;
|
int n, x;
|
||||||
short lg;
|
short lg;
|
||||||
bool rcb;
|
bool rcb;
|
||||||
RCODE rc;
|
RCODE rc;
|
||||||
@@ -720,9 +720,18 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
|
|||||||
|
|
||||||
if (!ptdb)
|
if (!ptdb)
|
||||||
return RC_FX;
|
return RC_FX;
|
||||||
if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
|
else
|
||||||
|
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
|
||||||
|
|
||||||
|
if (!x) {
|
||||||
sprintf(g->Message, "CntIndexRead: Table %s is not indexable", ptdb->GetName());
|
sprintf(g->Message, "CntIndexRead: Table %s is not indexable", ptdb->GetName());
|
||||||
return RC_FX;
|
return RC_FX;
|
||||||
|
} else if (x == 2) {
|
||||||
|
// Remote index
|
||||||
|
if (ptdb->ReadKey(g, op, key, len))
|
||||||
|
return RC_FX;
|
||||||
|
|
||||||
|
goto rnd;
|
||||||
} else
|
} else
|
||||||
tdbp= (PTDBDOX)ptdb;
|
tdbp= (PTDBDOX)ptdb;
|
||||||
|
|
||||||
@@ -782,8 +791,9 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
|
|||||||
xbp->SetOp(op);
|
xbp->SetOp(op);
|
||||||
xbp->SetNth(0);
|
xbp->SetNth(0);
|
||||||
|
|
||||||
if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK)
|
rnd:
|
||||||
rc= EvalColumns(g, tdbp);
|
if ((rc= (RCODE)ptdb->ReadDB(g)) == RC_OK)
|
||||||
|
rc= EvalColumns(g, ptdb);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
} // end of CntIndexRead
|
} // end of CntIndexRead
|
||||||
@@ -795,7 +805,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
|
|||||||
bool *incl, key_part_map *kmap)
|
bool *incl, key_part_map *kmap)
|
||||||
{
|
{
|
||||||
const uchar *p, *kp;
|
const uchar *p, *kp;
|
||||||
int i, n, k[2];
|
int i, n, x, k[2];
|
||||||
short lg;
|
short lg;
|
||||||
bool b, rcb;
|
bool b, rcb;
|
||||||
PVAL valp;
|
PVAL valp;
|
||||||
@@ -805,10 +815,16 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
|
|||||||
|
|
||||||
if (!ptdb)
|
if (!ptdb)
|
||||||
return -1;
|
return -1;
|
||||||
else if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
|
|
||||||
|
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
|
||||||
|
|
||||||
|
if (!x) {
|
||||||
sprintf(g->Message, "CntIndexRange: Table %s is not indexable", ptdb->GetName());
|
sprintf(g->Message, "CntIndexRange: Table %s is not indexable", ptdb->GetName());
|
||||||
DBUG_PRINT("Range", ("%s", g->Message));
|
DBUG_PRINT("Range", ("%s", g->Message));
|
||||||
return -1;
|
return -1;
|
||||||
|
} else if (x == 2) {
|
||||||
|
// Remote index
|
||||||
|
return 2;
|
||||||
} else
|
} else
|
||||||
tdbp= (PTDBDOX)ptdb;
|
tdbp= (PTDBDOX)ptdb;
|
||||||
|
|
||||||
|
@@ -1218,9 +1218,10 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
|
|||||||
if (!xp->CheckQuery(valid_query_id) && tdbp
|
if (!xp->CheckQuery(valid_query_id) && tdbp
|
||||||
&& !stricmp(tdbp->GetName(), table_name)
|
&& !stricmp(tdbp->GetName(), table_name)
|
||||||
&& (tdbp->GetMode() == xmod
|
&& (tdbp->GetMode() == xmod
|
||||||
|
|| (tdbp->GetMode() == MODE_READ && xmod == MODE_READX)
|
||||||
|| tdbp->GetAmType() == TYPE_AM_XML)) {
|
|| tdbp->GetAmType() == TYPE_AM_XML)) {
|
||||||
tp= tdbp;
|
tp= tdbp;
|
||||||
// tp->SetMode(xmod);
|
tp->SetMode(xmod);
|
||||||
} else if ((tp= CntGetTDB(g, table_name, xmod, this))) {
|
} else if ((tp= CntGetTDB(g, table_name, xmod, this))) {
|
||||||
valid_query_id= xp->last_query_id;
|
valid_query_id= xp->last_query_id;
|
||||||
tp->SetMode(xmod);
|
tp->SetMode(xmod);
|
||||||
@@ -1613,6 +1614,88 @@ int ha_connect::CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf)
|
|||||||
} // end of dummy CheckRecord
|
} // end of dummy CheckRecord
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Return the where clause for remote indexed read. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q,
|
||||||
|
const void *key, int klen)
|
||||||
|
{
|
||||||
|
const uchar *ptr;
|
||||||
|
uint rem, len, stlen; //, prtlen;
|
||||||
|
bool nq, b= false;
|
||||||
|
Field *fp;
|
||||||
|
KEY *kfp;
|
||||||
|
KEY_PART_INFO *kpart;
|
||||||
|
|
||||||
|
if (active_index == MAX_KEY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
strcat(qry, " WHERE (");
|
||||||
|
kfp= &table->key_info[active_index];
|
||||||
|
rem= kfp->user_defined_key_parts,
|
||||||
|
len= klen,
|
||||||
|
ptr= (const uchar *)key;
|
||||||
|
|
||||||
|
for (kpart= kfp->key_part; rem; rem--, kpart++) {
|
||||||
|
fp= kpart->field;
|
||||||
|
stlen= kpart->store_length;
|
||||||
|
// prtlen= min(stlen, len);
|
||||||
|
nq= fp->str_needs_quotes();
|
||||||
|
|
||||||
|
if (b)
|
||||||
|
strcat(qry, " AND ");
|
||||||
|
else
|
||||||
|
b= true;
|
||||||
|
|
||||||
|
strcat(strncat(strcat(qry, q), fp->field_name, strlen(fp->field_name)), q);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case OP_EQ:
|
||||||
|
case OP_GT:
|
||||||
|
case OP_GE:
|
||||||
|
strcat(qry, GetValStr(op, false));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcat(qry, " ??? ");
|
||||||
|
} // endwitch op
|
||||||
|
|
||||||
|
if (nq)
|
||||||
|
strcat(qry, "'");
|
||||||
|
|
||||||
|
if (kpart->key_part_flag & HA_VAR_LENGTH_PART) {
|
||||||
|
String varchar;
|
||||||
|
uint var_length= uint2korr(ptr);
|
||||||
|
|
||||||
|
varchar.set_quick((char*) ptr+HA_KEY_BLOB_LENGTH,
|
||||||
|
var_length, &my_charset_bin);
|
||||||
|
strncat(qry, varchar.ptr(), varchar.length());
|
||||||
|
} else {
|
||||||
|
char strbuff[MAX_FIELD_WIDTH];
|
||||||
|
String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res;
|
||||||
|
|
||||||
|
res= fp->val_str(&str, ptr);
|
||||||
|
strncat(qry, res->ptr(), res->length());
|
||||||
|
} // endif flag
|
||||||
|
|
||||||
|
if (nq)
|
||||||
|
strcat(qry, "'");
|
||||||
|
|
||||||
|
if (stlen >= len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
len-= stlen;
|
||||||
|
|
||||||
|
/* For nullable columns, null-byte is already skipped before, that is
|
||||||
|
ptr was incremented by 1. Since store_length still counts null-byte,
|
||||||
|
we need to subtract 1 from store_length. */
|
||||||
|
ptr+= stlen - test(kpart->null_bit);
|
||||||
|
} // endfor kpart
|
||||||
|
|
||||||
|
strcat(qry, ")");
|
||||||
|
return false;
|
||||||
|
} // end of MakeKeyWhere
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Return the string representing an operator. */
|
/* Return the string representing an operator. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1738,7 +1821,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
p1= p2 + strlen(p2);
|
p1= p2 + strlen(p2);
|
||||||
strcpy(p1, GetValStr(vop, FALSE));
|
strcpy(p1, GetValStr(vop, false));
|
||||||
p2= p1 + strlen(p1);
|
p2= p1 + strlen(p1);
|
||||||
} // endif CheckCond
|
} // endif CheckCond
|
||||||
|
|
||||||
@@ -2092,7 +2175,9 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
|
|||||||
dup->Check |= CHK_OPT;
|
dup->Check |= CHK_OPT;
|
||||||
|
|
||||||
if (tdbp) {
|
if (tdbp) {
|
||||||
if (!((PTDBASE)tdbp)->GetDef()->Indexable()) {
|
if (((PTDBASE)tdbp)->GetDef()->Indexable() == 2) {
|
||||||
|
// Nothing to do for remote index
|
||||||
|
} else if (!((PTDBASE)tdbp)->GetDef()->Indexable()) {
|
||||||
sprintf(g->Message, "optimize: Table %s is not indexable", tdbp->GetName());
|
sprintf(g->Message, "optimize: Table %s is not indexable", tdbp->GetName());
|
||||||
my_message(ER_INDEX_REBUILD, g->Message, MYF(0));
|
my_message(ER_INDEX_REBUILD, g->Message, MYF(0));
|
||||||
rc= HA_ERR_UNSUPPORTED;
|
rc= HA_ERR_UNSUPPORTED;
|
||||||
@@ -2306,6 +2391,18 @@ int ha_connect::index_init(uint idx, bool sorted)
|
|||||||
if (xtrace)
|
if (xtrace)
|
||||||
htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted);
|
htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted);
|
||||||
|
|
||||||
|
if (GetIndexType(GetRealType()) == 2) {
|
||||||
|
// This is a remote index
|
||||||
|
xmod= MODE_READX;
|
||||||
|
|
||||||
|
if (!(rc= rnd_init(0))) {
|
||||||
|
active_index= idx;
|
||||||
|
indexing= 2; // TO DO: mul?
|
||||||
|
} //endif rc
|
||||||
|
|
||||||
|
DBUG_RETURN(rc);
|
||||||
|
} // endif index type
|
||||||
|
|
||||||
if ((rc= rnd_init(0)))
|
if ((rc= rnd_init(0)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -2821,12 +2918,16 @@ int ha_connect::info(uint flag)
|
|||||||
if (cat && table)
|
if (cat && table)
|
||||||
cat->SetDataPath(g, table->s->db.str);
|
cat->SetDataPath(g, table->s->db.str);
|
||||||
else
|
else
|
||||||
return HA_ERR_INTERNAL_ERROR; // Should never happen
|
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
|
||||||
|
|
||||||
tdbp= GetTDB(g);
|
tdbp= GetTDB(g);
|
||||||
} // endif tdbp
|
} // endif tdbp
|
||||||
|
|
||||||
valid_info= CntInfo(g, tdbp, &xinfo);
|
valid_info= CntInfo(g, tdbp, &xinfo);
|
||||||
|
|
||||||
|
if (((signed)xinfo.records) < 0)
|
||||||
|
DBUG_RETURN(HA_ERR_INITIALIZATION); // Error in Cardinality
|
||||||
|
|
||||||
} // endif valid_info
|
} // endif valid_info
|
||||||
|
|
||||||
if (flag & HA_STATUS_VARIABLE) {
|
if (flag & HA_STATUS_VARIABLE) {
|
||||||
@@ -3086,7 +3187,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
|
|||||||
newmode= MODE_ALTER;
|
newmode= MODE_ALTER;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
htrc("Unsupported sql_command=%d", thd_sql_command(thd));
|
htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
|
||||||
strcpy(g->Message, "CONNECT Unsupported command");
|
strcpy(g->Message, "CONNECT Unsupported command");
|
||||||
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
|
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
|
||||||
newmode= MODE_ERROR;
|
newmode= MODE_ERROR;
|
||||||
@@ -3131,7 +3232,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
|
|||||||
newmode= MODE_ALTER;
|
newmode= MODE_ALTER;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
htrc("Unsupported sql_command=%d", thd_sql_command(thd));
|
htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
|
||||||
strcpy(g->Message, "CONNECT Unsupported command");
|
strcpy(g->Message, "CONNECT Unsupported command");
|
||||||
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
|
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
|
||||||
newmode= MODE_ERROR;
|
newmode= MODE_ERROR;
|
||||||
@@ -3255,87 +3356,88 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||||||
// DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error
|
// DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error
|
||||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
|
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
} // endif Indexable
|
} else if (((PTDBASE)tdbp)->GetDef()->Indexable() == 1) {
|
||||||
|
bool oldsep= ((PCHK)g->Xchk)->oldsep;
|
||||||
|
bool newsep= ((PCHK)g->Xchk)->newsep;
|
||||||
|
PTDBDOS tdp= (PTDBDOS)tdbp;
|
||||||
|
|
||||||
bool oldsep= ((PCHK)g->Xchk)->oldsep;
|
PDOSDEF ddp= (PDOSDEF)tdp->GetDef();
|
||||||
bool newsep= ((PCHK)g->Xchk)->newsep;
|
PIXDEF xp, xp1, xp2, drp=NULL, adp= NULL;
|
||||||
PTDBDOS tdp= (PTDBDOS)tdbp;
|
PIXDEF oldpix= ((PCHK)g->Xchk)->oldpix;
|
||||||
|
PIXDEF newpix= ((PCHK)g->Xchk)->newpix;
|
||||||
|
PIXDEF *xlst, *xprc;
|
||||||
|
|
||||||
PDOSDEF ddp= (PDOSDEF)tdp->GetDef();
|
ddp->SetIndx(oldpix);
|
||||||
PIXDEF xp, xp1, xp2, drp=NULL, adp= NULL;
|
|
||||||
PIXDEF oldpix= ((PCHK)g->Xchk)->oldpix;
|
|
||||||
PIXDEF newpix= ((PCHK)g->Xchk)->newpix;
|
|
||||||
PIXDEF *xlst, *xprc;
|
|
||||||
|
|
||||||
ddp->SetIndx(oldpix);
|
if (oldsep != newsep) {
|
||||||
|
// All indexes have to be remade
|
||||||
if (oldsep != newsep) {
|
|
||||||
// All indexes have to be remade
|
|
||||||
ddp->DeleteIndexFile(g, NULL);
|
|
||||||
oldpix= NULL;
|
|
||||||
ddp->SetIndx(NULL);
|
|
||||||
SetBooleanOption("Sepindex", newsep);
|
|
||||||
} else if (newsep) {
|
|
||||||
// Make the list of dropped indexes
|
|
||||||
xlst= &drp; xprc= &oldpix;
|
|
||||||
|
|
||||||
for (xp2= oldpix; xp2; xp2= xp) {
|
|
||||||
for (xp1= newpix; xp1; xp1= xp1->Next)
|
|
||||||
if (IsSameIndex(xp1, xp2))
|
|
||||||
break; // Index not to drop
|
|
||||||
|
|
||||||
xp= xp2->GetNext();
|
|
||||||
|
|
||||||
if (!xp1) {
|
|
||||||
*xlst= xp2;
|
|
||||||
*xprc= xp;
|
|
||||||
*(xlst= &xp2->Next)= NULL;
|
|
||||||
} else
|
|
||||||
xprc= &xp2->Next;
|
|
||||||
|
|
||||||
} // endfor xp2
|
|
||||||
|
|
||||||
if (drp) {
|
|
||||||
// Here we erase the index files
|
|
||||||
ddp->DeleteIndexFile(g, drp);
|
|
||||||
} // endif xp1
|
|
||||||
|
|
||||||
} else if (oldpix) {
|
|
||||||
// TODO: optimize the case of just adding new indexes
|
|
||||||
if (!newpix)
|
|
||||||
ddp->DeleteIndexFile(g, NULL);
|
ddp->DeleteIndexFile(g, NULL);
|
||||||
|
oldpix= NULL;
|
||||||
|
ddp->SetIndx(NULL);
|
||||||
|
SetBooleanOption("Sepindex", newsep);
|
||||||
|
} else if (newsep) {
|
||||||
|
// Make the list of dropped indexes
|
||||||
|
xlst= &drp; xprc= &oldpix;
|
||||||
|
|
||||||
oldpix= NULL; // To remake all indexes
|
for (xp2= oldpix; xp2; xp2= xp) {
|
||||||
ddp->SetIndx(NULL);
|
for (xp1= newpix; xp1; xp1= xp1->Next)
|
||||||
} // endif sepindex
|
if (IsSameIndex(xp1, xp2))
|
||||||
|
break; // Index not to drop
|
||||||
|
|
||||||
// Make the list of new created indexes
|
xp= xp2->GetNext();
|
||||||
xlst= &adp; xprc= &newpix;
|
|
||||||
|
|
||||||
for (xp1= newpix; xp1; xp1= xp) {
|
if (!xp1) {
|
||||||
for (xp2= oldpix; xp2; xp2= xp2->Next)
|
*xlst= xp2;
|
||||||
if (IsSameIndex(xp1, xp2))
|
*xprc= xp;
|
||||||
break; // Index already made
|
*(xlst= &xp2->Next)= NULL;
|
||||||
|
} else
|
||||||
|
xprc= &xp2->Next;
|
||||||
|
|
||||||
xp= xp1->Next;
|
} // endfor xp2
|
||||||
|
|
||||||
if (!xp2) {
|
if (drp) {
|
||||||
*xlst= xp1;
|
// Here we erase the index files
|
||||||
*xprc= xp;
|
ddp->DeleteIndexFile(g, drp);
|
||||||
*(xlst= &xp1->Next)= NULL;
|
} // endif xp1
|
||||||
} else
|
|
||||||
xprc= &xp1->Next;
|
|
||||||
|
|
||||||
} // endfor xp1
|
} else if (oldpix) {
|
||||||
|
// TODO: optimize the case of just adding new indexes
|
||||||
|
if (!newpix)
|
||||||
|
ddp->DeleteIndexFile(g, NULL);
|
||||||
|
|
||||||
if (adp)
|
oldpix= NULL; // To remake all indexes
|
||||||
// Here we do make the new indexes
|
ddp->SetIndx(NULL);
|
||||||
if (tdp->MakeIndex(g, adp, true) == RC_FX) {
|
} // endif sepindex
|
||||||
// Make it a warning to avoid crash
|
|
||||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
// Make the list of new created indexes
|
||||||
0, g->Message);
|
xlst= &adp; xprc= &newpix;
|
||||||
rc= 0;
|
|
||||||
} // endif MakeIndex
|
for (xp1= newpix; xp1; xp1= xp) {
|
||||||
|
for (xp2= oldpix; xp2; xp2= xp2->Next)
|
||||||
|
if (IsSameIndex(xp1, xp2))
|
||||||
|
break; // Index already made
|
||||||
|
|
||||||
|
xp= xp1->Next;
|
||||||
|
|
||||||
|
if (!xp2) {
|
||||||
|
*xlst= xp1;
|
||||||
|
*xprc= xp;
|
||||||
|
*(xlst= &xp1->Next)= NULL;
|
||||||
|
} else
|
||||||
|
xprc= &xp1->Next;
|
||||||
|
|
||||||
|
} // endfor xp1
|
||||||
|
|
||||||
|
if (adp)
|
||||||
|
// Here we do make the new indexes
|
||||||
|
if (tdp->MakeIndex(g, adp, true) == RC_FX) {
|
||||||
|
// Make it a warning to avoid crash
|
||||||
|
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
|
0, g->Message);
|
||||||
|
rc= 0;
|
||||||
|
} // endif MakeIndex
|
||||||
|
|
||||||
|
} // endif indexable
|
||||||
|
|
||||||
} // endif Tdbp
|
} // endif Tdbp
|
||||||
|
|
||||||
@@ -4831,7 +4933,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
|||||||
sprintf(g->Message, "Table type %s is not indexable", options->type);
|
sprintf(g->Message, "Table type %s is not indexable", options->type);
|
||||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
rc= HA_ERR_UNSUPPORTED;
|
rc= HA_ERR_UNSUPPORTED;
|
||||||
} // endif Indexable
|
} // endif index type
|
||||||
|
|
||||||
} // endif xdp
|
} // endif xdp
|
||||||
|
|
||||||
@@ -4840,62 +4942,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
|||||||
my_message(ER_UNKNOWN_ERROR,
|
my_message(ER_UNKNOWN_ERROR,
|
||||||
"CONNECT index modification should be in-place", MYF(0));
|
"CONNECT index modification should be in-place", MYF(0));
|
||||||
DBUG_RETURN(HA_ERR_UNSUPPORTED);
|
DBUG_RETURN(HA_ERR_UNSUPPORTED);
|
||||||
#if 0
|
|
||||||
PIXDEF xdp= GetIndexInfo();
|
|
||||||
PCHK xcp= (PCHK)g->Xchk;
|
|
||||||
|
|
||||||
if (xdp) {
|
|
||||||
if (!IsTypeIndexable(type)) {
|
|
||||||
g->Xchk= NULL;
|
|
||||||
sprintf(g->Message, "Table type %s is not indexable", options->type);
|
|
||||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
|
||||||
rc= HA_ERR_INTERNAL_ERROR;
|
|
||||||
} else {
|
|
||||||
xcp->newpix= xdp;
|
|
||||||
xcp->newsep= GetBooleanOption("Sepindex", false);
|
|
||||||
} // endif Indexable
|
|
||||||
|
|
||||||
} else if (!xcp->oldpix)
|
|
||||||
g->Xchk= NULL;
|
|
||||||
|
|
||||||
if (xtrace && g->Xchk)
|
|
||||||
htrc("oldsep=%d newsep=%d oldpix=%p newpix=%p\n",
|
|
||||||
xcp->oldsep, xcp->newsep, xcp->oldpix, xcp->newpix);
|
|
||||||
|
|
||||||
// if (g->Xchk &&
|
|
||||||
// (sqlcom != SQLCOM_CREATE_INDEX && sqlcom != SQLCOM_DROP_INDEX)) {
|
|
||||||
if (g->Xchk) {
|
|
||||||
PIXDEF xp1, xp2;
|
|
||||||
bool b= false; // true if index changes
|
|
||||||
|
|
||||||
if (xcp->oldsep == xcp->newsep) {
|
|
||||||
for (xp1= xcp->newpix, xp2= xcp->oldpix;
|
|
||||||
xp1 || xp2;
|
|
||||||
xp1= xp1->Next, xp2= xp2->Next)
|
|
||||||
if (!xp1 || !xp2 || !IsSameIndex(xp1, xp2)) {
|
|
||||||
b= true;
|
|
||||||
break;
|
|
||||||
} // endif xp1
|
|
||||||
|
|
||||||
} else
|
|
||||||
b= true;
|
|
||||||
|
|
||||||
if (!b)
|
|
||||||
g->Xchk= NULL;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (b) {
|
|
||||||
// CONNECT does not support indexing via ALTER TABLE
|
|
||||||
my_message(ER_UNKNOWN_ERROR,
|
|
||||||
"CONNECT does not support index modification via ALTER TABLE",
|
|
||||||
MYF(0));
|
|
||||||
DBUG_RETURN(HA_ERR_UNSUPPORTED);
|
|
||||||
} // endif b
|
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
} // endif Xchk
|
|
||||||
|
|
||||||
#endif // 0
|
|
||||||
} // endif Xchk
|
} // endif Xchk
|
||||||
|
|
||||||
table= st;
|
table= st;
|
||||||
|
@@ -198,6 +198,8 @@ public:
|
|||||||
int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
|
int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
|
||||||
int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL,
|
int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL,
|
||||||
uint key_len= 0);
|
uint key_len= 0);
|
||||||
|
bool MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q,
|
||||||
|
const void *key, int klen);
|
||||||
|
|
||||||
/** @brief
|
/** @brief
|
||||||
The name that will be used for display purposes.
|
The name that will be used for display purposes.
|
||||||
|
@@ -275,9 +275,10 @@ int GetIndexType(TABTYPE type)
|
|||||||
xtyp= 1;
|
xtyp= 1;
|
||||||
break;
|
break;
|
||||||
case TAB_MYSQL:
|
case TAB_MYSQL:
|
||||||
|
// case TAB_ODBC:
|
||||||
|
xtyp= 2;
|
||||||
|
break;
|
||||||
case TAB_ODBC:
|
case TAB_ODBC:
|
||||||
// xtyp= 2; Remote indexes not implemented yet
|
|
||||||
// break;
|
|
||||||
default:
|
default:
|
||||||
xtyp= 0;
|
xtyp= 0;
|
||||||
break;
|
break;
|
||||||
|
@@ -158,6 +158,7 @@ enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
|
|||||||
enum MODE {MODE_ERROR = -1, /* Invalid mode */
|
enum MODE {MODE_ERROR = -1, /* Invalid mode */
|
||||||
MODE_ANY = 0, /* Unspecified mode */
|
MODE_ANY = 0, /* Unspecified mode */
|
||||||
MODE_READ = 10, /* Input/Output mode */
|
MODE_READ = 10, /* Input/Output mode */
|
||||||
|
MODE_READX = 11, /* Read indexed mode */
|
||||||
MODE_WRITE = 20, /* Input/Output mode */
|
MODE_WRITE = 20, /* Input/Output mode */
|
||||||
MODE_UPDATE = 30, /* Input/Output mode */
|
MODE_UPDATE = 30, /* Input/Output mode */
|
||||||
MODE_INSERT = 40, /* Input/Output mode */
|
MODE_INSERT = 40, /* Input/Output mode */
|
||||||
|
@@ -31,6 +31,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
|
|||||||
PSZ GetName(void) {return Name;}
|
PSZ GetName(void) {return Name;}
|
||||||
PSZ GetDB(void) {return (PSZ)Database;}
|
PSZ GetDB(void) {return (PSZ)Database;}
|
||||||
PCOLDEF GetCols(void) {return To_Cols;}
|
PCOLDEF GetCols(void) {return To_Cols;}
|
||||||
|
PHC GetHandler(void) {return Hc;}
|
||||||
void SetCols(PCOLDEF pcd) {To_Cols = pcd;}
|
void SetCols(PCOLDEF pcd) {To_Cols = pcd;}
|
||||||
PCATLG GetCat(void) {return Cat;}
|
PCATLG GetCat(void) {return Cat;}
|
||||||
virtual const char *GetType(void) = 0;
|
virtual const char *GetType(void) = 0;
|
||||||
@@ -45,7 +46,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
|
|||||||
int GetSizeCatInfo(PSZ what, PSZ sdef);
|
int GetSizeCatInfo(PSZ what, PSZ sdef);
|
||||||
int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size);
|
int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size);
|
||||||
char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef);
|
char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef);
|
||||||
virtual bool Indexable(void) {return false;}
|
virtual int Indexable(void) {return 0;}
|
||||||
virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) = 0;
|
virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) = 0;
|
||||||
virtual PTDB GetTable(PGLOBAL g, MODE mode) = 0;
|
virtual PTDB GetTable(PGLOBAL g, MODE mode) = 0;
|
||||||
|
|
||||||
|
@@ -49,7 +49,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
|
|||||||
int GetEnding(void) {return Ending;}
|
int GetEnding(void) {return Ending;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual bool Indexable(void) {return Compressed != 1;}
|
virtual int Indexable(void) {return (Compressed != 1) ? 1 : 0;}
|
||||||
virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
|
virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
|
||||||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
virtual PTDB GetTable(PGLOBAL g, MODE mode);
|
virtual PTDB GetTable(PGLOBAL g, MODE mode);
|
||||||
@@ -146,10 +146,10 @@ class DllExport TDBDOS : public TDBASE {
|
|||||||
virtual int ReadBuffer(PGLOBAL g) {return Txfp->ReadBuffer(g);}
|
virtual int ReadBuffer(PGLOBAL g) {return Txfp->ReadBuffer(g);}
|
||||||
|
|
||||||
// Specific routine
|
// Specific routine
|
||||||
virtual int EstimatedLength(PGLOBAL g);
|
virtual int EstimatedLength(PGLOBAL g);
|
||||||
|
|
||||||
// Optimization routines
|
// Optimization routines
|
||||||
int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
|
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
|
@@ -61,6 +61,7 @@
|
|||||||
#include "tabmysql.h"
|
#include "tabmysql.h"
|
||||||
#include "valblk.h"
|
#include "valblk.h"
|
||||||
#include "tabutil.h"
|
#include "tabutil.h"
|
||||||
|
#include "ha_connect.h"
|
||||||
|
|
||||||
#if defined(_CONSOLE)
|
#if defined(_CONSOLE)
|
||||||
void PrintResult(PGLOBAL, PSEM, PQRYRES);
|
void PrintResult(PGLOBAL, PSEM, PQRYRES);
|
||||||
@@ -481,16 +482,16 @@ PCOL TDBMYSQL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
|||||||
/* Note: when implementing EOM filtering, column only used in local */
|
/* Note: when implementing EOM filtering, column only used in local */
|
||||||
/* filter should be removed from column list. */
|
/* filter should be removed from column list. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBMYSQL::MakeSelect(PGLOBAL g)
|
bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
|
||||||
{
|
{
|
||||||
char *tk = "`";
|
char *tk = "`";
|
||||||
int rank = 0;
|
int len = 0, rank = 0;
|
||||||
bool b = FALSE;
|
bool b = false;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
//PDBUSER dup = PlgGetUser(g);
|
//PDBUSER dup = PlgGetUser(g);
|
||||||
|
|
||||||
if (Query)
|
if (Query)
|
||||||
return FALSE; // already done
|
return false; // already done
|
||||||
|
|
||||||
if (Srcdef) {
|
if (Srcdef) {
|
||||||
Query = Srcdef;
|
Query = Srcdef;
|
||||||
@@ -506,12 +507,12 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
|
|||||||
if (!colp->IsSpecial()) {
|
if (!colp->IsSpecial()) {
|
||||||
// if (colp->IsSpecial()) {
|
// if (colp->IsSpecial()) {
|
||||||
// strcpy(g->Message, MSG(NO_SPEC_COL));
|
// strcpy(g->Message, MSG(NO_SPEC_COL));
|
||||||
// return TRUE;
|
// return true;
|
||||||
// } else {
|
// } else {
|
||||||
if (b)
|
if (b)
|
||||||
strcat(Query, ", ");
|
strcat(Query, ", ");
|
||||||
else
|
else
|
||||||
b = TRUE;
|
b = true;
|
||||||
|
|
||||||
strcat(strcat(strcat(Query, tk), colp->GetName()), tk);
|
strcat(strcat(strcat(Query, tk), colp->GetName()), tk);
|
||||||
((PMYCOL)colp)->Rank = rank++;
|
((PMYCOL)colp)->Rank = rank++;
|
||||||
@@ -526,16 +527,24 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
|
|||||||
} // endif ncol
|
} // endif ncol
|
||||||
|
|
||||||
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
|
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
|
||||||
|
len = strlen(Query);
|
||||||
|
|
||||||
if (To_CondFil)
|
if (To_CondFil) {
|
||||||
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
|
if (!mx) {
|
||||||
|
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
|
||||||
|
len = strlen(Query) + 1;
|
||||||
|
} else
|
||||||
|
len += (strlen(To_CondFil->Body) + 256);
|
||||||
|
|
||||||
|
} else
|
||||||
|
len += (mx ? 256 : 1);
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("Query=%s\n", Query);
|
htrc("Query=%s\n", Query);
|
||||||
|
|
||||||
// Now we know how much to suballocate
|
// Now we know how much to suballocate
|
||||||
PlugSubAlloc(g, NULL, strlen(Query) + 1);
|
PlugSubAlloc(g, NULL, len);
|
||||||
return FALSE;
|
return false;
|
||||||
} // end of MakeSelect
|
} // end of MakeSelect
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -833,9 +842,9 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Allocate whatever is used for getting results. */
|
/* Allocate whatever is used for getting results. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (Mode == MODE_READ) {
|
if (Mode == MODE_READ || Mode == MODE_READX) {
|
||||||
if (!MakeSelect(g))
|
MakeSelect(g, Mode == MODE_READX);
|
||||||
m_Rc = Myc.ExecSQL(g, Query);
|
m_Rc = (Mode == MODE_READ) ? Myc.ExecSQL(g, Query) : RC_OK;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (!Myc.m_Res || !Myc.m_Fields) {
|
if (!Myc.m_Res || !Myc.m_Fields) {
|
||||||
@@ -994,6 +1003,36 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
|
|||||||
|
|
||||||
} // end of SendCommand
|
} // end of SendCommand
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Data Base indexed read routine for MYSQL access method. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
|
||||||
|
{
|
||||||
|
int oldlen = strlen(Query);
|
||||||
|
bool rc;
|
||||||
|
|
||||||
|
if (op == OP_NEXT)
|
||||||
|
return false;
|
||||||
|
else if (op == OP_FIRST) {
|
||||||
|
if (To_CondFil)
|
||||||
|
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (Myc.m_Res)
|
||||||
|
Myc.FreeResult();
|
||||||
|
|
||||||
|
rc = To_Def->GetHandler()->MakeKeyWhere(g, Query, op, "`", key, len);
|
||||||
|
|
||||||
|
if (To_CondFil)
|
||||||
|
strcat(strcat(strcat(Query, " AND ("), To_CondFil->Body), ")");
|
||||||
|
|
||||||
|
} // endif's op
|
||||||
|
|
||||||
|
m_Rc = Myc.ExecSQL(g, Query);
|
||||||
|
Query[oldlen] = 0;
|
||||||
|
return false;
|
||||||
|
} // end of ReadKey
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Data Base read routine for MYSQL access method. */
|
/* Data Base read routine for MYSQL access method. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1451,7 +1490,7 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
|
|||||||
|
|
||||||
Use = USE_OPEN; // Do it now in case we are recursively called
|
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||||
|
|
||||||
if (Mode != MODE_READ) {
|
if (Mode != MODE_READ && Mode != MODE_READX) {
|
||||||
strcpy(g->Message, "No INSERT/DELETE/UPDATE of MYSQL EXEC tables");
|
strcpy(g->Message, "No INSERT/DELETE/UPDATE of MYSQL EXEC tables");
|
||||||
return true;
|
return true;
|
||||||
} // endif Mode
|
} // endif Mode
|
||||||
|
@@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
inline int GetPortnumber(void) {return Portnumber;}
|
inline int GetPortnumber(void) {return Portnumber;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
virtual int Indexable(void) {return 2;}
|
||||||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
||||||
bool ParseURL(PGLOBAL g, char *url, bool b = true);
|
bool ParseURL(PGLOBAL g, char *url, bool b = true);
|
||||||
@@ -96,6 +97,7 @@ class TDBMYSQL : public TDBASE {
|
|||||||
virtual int WriteDB(PGLOBAL g);
|
virtual int WriteDB(PGLOBAL g);
|
||||||
virtual int DeleteDB(PGLOBAL g, int irc);
|
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||||
virtual void CloseDB(PGLOBAL g);
|
virtual void CloseDB(PGLOBAL g);
|
||||||
|
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len);
|
||||||
|
|
||||||
// Specific routines
|
// Specific routines
|
||||||
bool SetColumnRanks(PGLOBAL g);
|
bool SetColumnRanks(PGLOBAL g);
|
||||||
@@ -104,7 +106,7 @@ class TDBMYSQL : public TDBASE {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal functions
|
// Internal functions
|
||||||
bool MakeSelect(PGLOBAL g);
|
bool MakeSelect(PGLOBAL g, bool mx);
|
||||||
bool MakeInsert(PGLOBAL g);
|
bool MakeInsert(PGLOBAL g);
|
||||||
int BindColumns(PGLOBAL g);
|
int BindColumns(PGLOBAL g);
|
||||||
int MakeCommand(PGLOBAL g);
|
int MakeCommand(PGLOBAL g);
|
||||||
|
@@ -752,7 +752,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Make the command and allocate whatever is used for getting results. */
|
/* Make the command and allocate whatever is used for getting results. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (Mode == MODE_READ) {
|
if (Mode == MODE_READ || Mode == MODE_READX) {
|
||||||
if ((Query = MakeSQL(g, false))) {
|
if ((Query = MakeSQL(g, false))) {
|
||||||
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
|
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
|
||||||
colp = (PODBCCOL)colp->GetNext())
|
colp = (PODBCCOL)colp->GetNext())
|
||||||
@@ -1315,7 +1315,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
|
|||||||
|
|
||||||
Use = USE_OPEN; // Do it now in case we are recursively called
|
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||||
|
|
||||||
if (Mode != MODE_READ) {
|
if (Mode != MODE_READ && Mode != MODE_READX) {
|
||||||
strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables");
|
strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables");
|
||||||
return true;
|
return true;
|
||||||
} // endif Mode
|
} // endif Mode
|
||||||
|
@@ -90,6 +90,7 @@ class TDBODBC : public TDBASE {
|
|||||||
virtual void ResetSize(void);
|
virtual void ResetSize(void);
|
||||||
virtual int GetAffectedRows(void) {return AftRows;}
|
virtual int GetAffectedRows(void) {return AftRows;}
|
||||||
virtual PSZ GetServer(void) {return "ODBC";}
|
virtual PSZ GetServer(void) {return "ODBC";}
|
||||||
|
virtual int Indexable(void) {return 2;}
|
||||||
|
|
||||||
// Database routines
|
// Database routines
|
||||||
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
||||||
@@ -100,6 +101,8 @@ class TDBODBC : public TDBASE {
|
|||||||
virtual int WriteDB(PGLOBAL g);
|
virtual int WriteDB(PGLOBAL g);
|
||||||
virtual int DeleteDB(PGLOBAL g, int irc);
|
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||||
virtual void CloseDB(PGLOBAL g);
|
virtual void CloseDB(PGLOBAL g);
|
||||||
|
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
|
||||||
|
{return true;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal functions
|
// Internal functions
|
||||||
|
@@ -79,7 +79,7 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
PTABLE tablep;
|
PTABLE tablep;
|
||||||
PTDBDOS tdbp;
|
PTDBASE tdbp;
|
||||||
PCATLG cat = PlgGetCatalog(g, true);
|
PCATLG cat = PlgGetCatalog(g, true);
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
@@ -87,13 +87,13 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
tablep = new(g) XTAB(name);
|
tablep = new(g) XTAB(name);
|
||||||
|
|
||||||
if (!(tdbp = (PTDBDOS)cat->GetTable(g, tablep)))
|
if (!(tdbp = (PTDBASE)cat->GetTable(g, tablep)))
|
||||||
rc = RC_NF;
|
rc = RC_NF;
|
||||||
else if (!tdbp->GetDef()->Indexable()) {
|
else if (!tdbp->GetDef()->Indexable()) {
|
||||||
sprintf(g->Message, MSG(TABLE_NO_INDEX), name);
|
sprintf(g->Message, MSG(TABLE_NO_INDEX), name);
|
||||||
rc = RC_NF;
|
rc = RC_NF;
|
||||||
} else if ((rc = tdbp->MakeIndex(g, pxdf, add)) == RC_INFO)
|
} else if ((rc = tdbp->MakeIndex(g, pxdf, add)) == RC_INFO)
|
||||||
rc = RC_OK; // No index
|
rc = RC_OK; // No or remote index
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
} // end of PlgMakeIndex
|
} // end of PlgMakeIndex
|
||||||
|
@@ -107,6 +107,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
|
|||||||
virtual int DeleteDB(PGLOBAL, int) = 0;
|
virtual int DeleteDB(PGLOBAL, int) = 0;
|
||||||
virtual void CloseDB(PGLOBAL) = 0;
|
virtual void CloseDB(PGLOBAL) = 0;
|
||||||
virtual int CheckWrite(PGLOBAL g) {return 0;}
|
virtual int CheckWrite(PGLOBAL g) {return 0;}
|
||||||
|
virtual bool ReadKey(PGLOBAL, OPVAL, const void *, int) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
@@ -176,6 +177,11 @@ class DllExport TDBASE : public TDB {
|
|||||||
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp);
|
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp);
|
||||||
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
|
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
|
||||||
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
|
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
|
||||||
|
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
|
||||||
|
{strcpy(g->Message, "Remote index"); return RC_INFO;}
|
||||||
|
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
|
||||||
|
{assert(false); return true;}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
|
Reference in New Issue
Block a user