mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
-Fix MDEV-4878. Table locking is now supported.
modified: storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/plgdbsem.h - Fiw a bug making records_in_range sometimes return a negative value. modified: storage/connect/xindex.cpp
This commit is contained in:
parent
8b3e07e15b
commit
bce59293fb
4 changed files with 184 additions and 113 deletions
|
@ -497,6 +497,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
|
|||
creat_query_id= (table && table->in_use) ? table->in_use->query_id : 0;
|
||||
stop= false;
|
||||
indexing= -1;
|
||||
locked= 0;
|
||||
data_file_name= NULL;
|
||||
index_file_name= NULL;
|
||||
enable_activate_all_index= 0;
|
||||
|
@ -1865,7 +1866,7 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
|
|||
DBUG_ENTER("ha_connect::open");
|
||||
|
||||
if (xtrace)
|
||||
printf("open: name=%s mode=%d test=%ud\n", name, mode, test_if_locked);
|
||||
printf("open: name=%s mode=%d test=%u\n", name, mode, test_if_locked);
|
||||
|
||||
if (!(share= get_share(name, table)))
|
||||
DBUG_RETURN(1);
|
||||
|
@ -1983,8 +1984,11 @@ int ha_connect::write_row(uchar *buf)
|
|||
PGLOBAL& g= xp->g;
|
||||
DBUG_ENTER("ha_connect::write_row");
|
||||
|
||||
// Open the table if it was not opened yet (possible ???)
|
||||
if (!IsOpened())
|
||||
// Open the table if it was not opened yet (locked)
|
||||
if (!IsOpened() || xmod != tdbp->GetMode()) {
|
||||
if (IsOpened())
|
||||
CloseTable(g);
|
||||
|
||||
if (OpenTable(g)) {
|
||||
if (strstr(g->Message, "read only"))
|
||||
rc= HA_ERR_TABLE_READONLY;
|
||||
|
@ -1994,6 +1998,8 @@ int ha_connect::write_row(uchar *buf)
|
|||
DBUG_RETURN(rc);
|
||||
} // endif tdbp
|
||||
|
||||
} // endif isopened
|
||||
|
||||
if (tdbp->GetMode() == MODE_ANY)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
|
@ -2112,6 +2118,13 @@ int ha_connect::index_init(uint idx, bool sorted)
|
|||
if ((rc= rnd_init(0)))
|
||||
return rc;
|
||||
|
||||
if (locked == 2) {
|
||||
// Indexes are not updated in lock write mode
|
||||
active_index= MAX_KEY;
|
||||
indexing= 0;
|
||||
DBUG_RETURN(0);
|
||||
} // endif locked
|
||||
|
||||
indexing= CntIndexInit(g, tdbp, (signed)idx);
|
||||
|
||||
if (indexing <= 0) {
|
||||
|
@ -2356,16 +2369,15 @@ int ha_connect::rnd_init(bool scan)
|
|||
printf("%p in rnd_init: scan=%d\n", this, scan);
|
||||
|
||||
if (g) {
|
||||
// Open the table if it was not opened yet (possible ???)
|
||||
if (!IsOpened()) {
|
||||
if (!table || xmod == MODE_INSERT)
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
if (!table || xmod == MODE_INSERT)
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
|
||||
if (OpenTable(g, xmod == MODE_DELETE))
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
// Close the table if it was opened yet (locked?)
|
||||
if (IsOpened())
|
||||
CloseTable(g);
|
||||
|
||||
} else
|
||||
void(CntRewindTable(g, tdbp)); // Read from beginning
|
||||
if (OpenTable(g, xmod == MODE_DELETE))
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
|
||||
} // endif g
|
||||
|
||||
|
@ -2780,6 +2792,153 @@ bool ha_connect::IsSameIndex(PIXDEF xp1, PIXDEF xp2)
|
|||
return b;
|
||||
} // end of IsSameIndex
|
||||
|
||||
MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
|
||||
MODE newmode, bool *chk, bool *cras)
|
||||
{
|
||||
if (xtrace) {
|
||||
LEX_STRING *query_string= thd_query_string(thd);
|
||||
printf("%p check_mode: cmdtype=%d\n", this, thd_sql_command(thd));
|
||||
printf("Cmd=%.*s\n", (int) query_string->length, query_string->str);
|
||||
} // endif xtrace
|
||||
|
||||
// Next code is temporarily replaced until sql_command is set
|
||||
stop= false;
|
||||
|
||||
if (newmode == MODE_WRITE) {
|
||||
switch (thd_sql_command(thd)) {
|
||||
case SQLCOM_LOCK_TABLES:
|
||||
locked= 2;
|
||||
case SQLCOM_CREATE_TABLE:
|
||||
case SQLCOM_INSERT:
|
||||
case SQLCOM_LOAD:
|
||||
case SQLCOM_INSERT_SELECT:
|
||||
newmode= MODE_INSERT;
|
||||
break;
|
||||
// case SQLCOM_REPLACE:
|
||||
// case SQLCOM_REPLACE_SELECT:
|
||||
// newmode= MODE_UPDATE; // To be checked
|
||||
// break;
|
||||
case SQLCOM_DELETE:
|
||||
case SQLCOM_DELETE_MULTI:
|
||||
case SQLCOM_TRUNCATE:
|
||||
newmode= MODE_DELETE;
|
||||
break;
|
||||
case SQLCOM_UPDATE:
|
||||
case SQLCOM_UPDATE_MULTI:
|
||||
newmode= MODE_UPDATE;
|
||||
break;
|
||||
case SQLCOM_SELECT:
|
||||
case SQLCOM_OPTIMIZE:
|
||||
newmode= MODE_READ;
|
||||
break;
|
||||
case SQLCOM_DROP_TABLE:
|
||||
case SQLCOM_RENAME_TABLE:
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
case SQLCOM_DROP_INDEX:
|
||||
case SQLCOM_CREATE_INDEX:
|
||||
newmode= MODE_ANY;
|
||||
// stop= true;
|
||||
break;
|
||||
case SQLCOM_CREATE_VIEW:
|
||||
case SQLCOM_DROP_VIEW:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported sql_command=%d", thd_sql_command(thd));
|
||||
strcpy(g->Message, "CONNECT Unsupported command");
|
||||
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
|
||||
newmode= MODE_ERROR;
|
||||
break;
|
||||
} // endswitch newmode
|
||||
|
||||
} else if (newmode == MODE_READ) {
|
||||
switch (thd_sql_command(thd)) {
|
||||
case SQLCOM_CREATE_TABLE:
|
||||
*chk= true;
|
||||
*cras= true;
|
||||
case SQLCOM_INSERT:
|
||||
case SQLCOM_LOAD:
|
||||
case SQLCOM_INSERT_SELECT:
|
||||
// case SQLCOM_REPLACE:
|
||||
// case SQLCOM_REPLACE_SELECT:
|
||||
case SQLCOM_DELETE:
|
||||
case SQLCOM_DELETE_MULTI:
|
||||
case SQLCOM_TRUNCATE:
|
||||
case SQLCOM_UPDATE:
|
||||
case SQLCOM_UPDATE_MULTI:
|
||||
case SQLCOM_SELECT:
|
||||
case SQLCOM_OPTIMIZE:
|
||||
break;
|
||||
case SQLCOM_LOCK_TABLES:
|
||||
locked= 1;
|
||||
break;
|
||||
case SQLCOM_DROP_INDEX:
|
||||
case SQLCOM_CREATE_INDEX:
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
*chk= true;
|
||||
// stop= true;
|
||||
case SQLCOM_DROP_TABLE:
|
||||
case SQLCOM_RENAME_TABLE:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
case SQLCOM_CREATE_VIEW:
|
||||
case SQLCOM_DROP_VIEW:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported sql_command=%d", thd_sql_command(thd));
|
||||
strcpy(g->Message, "CONNECT Unsupported command");
|
||||
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
|
||||
newmode= MODE_ERROR;
|
||||
break;
|
||||
} // endswitch newmode
|
||||
|
||||
} // endif's newmode
|
||||
|
||||
if (xtrace)
|
||||
printf("New mode=%d\n", newmode);
|
||||
|
||||
return newmode;
|
||||
} // end of check_mode
|
||||
|
||||
int ha_connect::start_stmt(THD *thd, thr_lock_type lock_type)
|
||||
{
|
||||
int rc= 0;
|
||||
bool chk=false, cras= false;
|
||||
MODE newmode;
|
||||
PGLOBAL g= GetPlug(thd, xp);
|
||||
DBUG_ENTER("ha_connect::start_stmt");
|
||||
|
||||
// Action will depend on lock_type
|
||||
switch (lock_type) {
|
||||
case TL_WRITE_ALLOW_WRITE:
|
||||
case TL_WRITE_CONCURRENT_INSERT:
|
||||
case TL_WRITE_DELAYED:
|
||||
case TL_WRITE_DEFAULT:
|
||||
case TL_WRITE_LOW_PRIORITY:
|
||||
case TL_WRITE:
|
||||
case TL_WRITE_ONLY:
|
||||
newmode= MODE_WRITE;
|
||||
break;
|
||||
case TL_READ:
|
||||
case TL_READ_WITH_SHARED_LOCKS:
|
||||
case TL_READ_HIGH_PRIORITY:
|
||||
case TL_READ_NO_INSERT:
|
||||
case TL_READ_DEFAULT:
|
||||
newmode= MODE_READ;
|
||||
break;
|
||||
case TL_UNLOCK:
|
||||
default:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
} // endswitch mode
|
||||
|
||||
xmod= CheckMode(g, thd, newmode, &chk, &cras);
|
||||
DBUG_RETURN((xmod == MODE_ERROR) ? HA_ERR_INTERNAL_ERROR : 0);
|
||||
} // end of start_stmt
|
||||
|
||||
/**
|
||||
@brief
|
||||
This create a lock on the table. If you are implementing a storage engine
|
||||
|
@ -2841,7 +3000,8 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||
|
||||
if (newmode == MODE_ANY) {
|
||||
// This is unlocking, do it by closing the table
|
||||
if (xp->CheckQueryID())
|
||||
if (xp->CheckQueryID() && thd_sql_command(thd) != SQLCOM_UNLOCK_TABLES
|
||||
&& thd_sql_command(thd) != SQLCOM_LOCK_TABLES)
|
||||
rc= 2; // Logical error ???
|
||||
else if (g->Xchk) {
|
||||
if (!tdbp || *tdbp->GetName() == '#') {
|
||||
|
@ -2939,109 +3099,15 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||
//#endif // !DEBUG
|
||||
} // endif Close
|
||||
|
||||
locked= 0;
|
||||
DBUG_RETURN(rc);
|
||||
} // endif MODE_ANY
|
||||
|
||||
if (xtrace) {
|
||||
LEX_STRING *query_string= thd_query_string(thd);
|
||||
printf("%p external_lock: cmdtype=%d\n", this, thd_sql_command(thd));
|
||||
printf("Cmd=%.*s\n", (int) query_string->length, query_string->str);
|
||||
} // endif xtrace
|
||||
// Table mode depends on the query type
|
||||
newmode= CheckMode(g, thd, newmode, &xcheck, &cras);
|
||||
|
||||
// Next code is temporarily replaced until sql_command is set
|
||||
stop= false;
|
||||
|
||||
if (newmode == MODE_WRITE) {
|
||||
switch (thd_sql_command(thd)) {
|
||||
case SQLCOM_CREATE_TABLE:
|
||||
case SQLCOM_INSERT:
|
||||
case SQLCOM_LOAD:
|
||||
case SQLCOM_INSERT_SELECT:
|
||||
newmode= MODE_INSERT;
|
||||
break;
|
||||
// case SQLCOM_REPLACE:
|
||||
// case SQLCOM_REPLACE_SELECT:
|
||||
// newmode= MODE_UPDATE; // To be checked
|
||||
// break;
|
||||
case SQLCOM_DELETE:
|
||||
case SQLCOM_DELETE_MULTI:
|
||||
case SQLCOM_TRUNCATE:
|
||||
newmode= MODE_DELETE;
|
||||
break;
|
||||
case SQLCOM_UPDATE:
|
||||
case SQLCOM_UPDATE_MULTI:
|
||||
newmode= MODE_UPDATE;
|
||||
break;
|
||||
case SQLCOM_SELECT:
|
||||
case SQLCOM_OPTIMIZE:
|
||||
newmode= MODE_READ;
|
||||
break;
|
||||
case SQLCOM_DROP_TABLE:
|
||||
case SQLCOM_RENAME_TABLE:
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
case SQLCOM_DROP_INDEX:
|
||||
case SQLCOM_CREATE_INDEX:
|
||||
newmode= MODE_ANY;
|
||||
// stop= true;
|
||||
break;
|
||||
case SQLCOM_CREATE_VIEW:
|
||||
case SQLCOM_DROP_VIEW:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported sql_command=%d", thd_sql_command(thd));
|
||||
strcpy(g->Message, "CONNECT Unsupported command");
|
||||
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
|
||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||
break;
|
||||
} // endswitch newmode
|
||||
|
||||
} else if (newmode == MODE_READ) {
|
||||
switch (thd_sql_command(thd)) {
|
||||
case SQLCOM_CREATE_TABLE:
|
||||
xcheck= true;
|
||||
cras= true;
|
||||
case SQLCOM_INSERT:
|
||||
case SQLCOM_LOAD:
|
||||
case SQLCOM_INSERT_SELECT:
|
||||
// case SQLCOM_REPLACE:
|
||||
// case SQLCOM_REPLACE_SELECT:
|
||||
case SQLCOM_DELETE:
|
||||
case SQLCOM_DELETE_MULTI:
|
||||
case SQLCOM_TRUNCATE:
|
||||
case SQLCOM_UPDATE:
|
||||
case SQLCOM_UPDATE_MULTI:
|
||||
case SQLCOM_SELECT:
|
||||
case SQLCOM_OPTIMIZE:
|
||||
break;
|
||||
case SQLCOM_DROP_INDEX:
|
||||
case SQLCOM_CREATE_INDEX:
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
xcheck= true;
|
||||
// stop= true;
|
||||
case SQLCOM_DROP_TABLE:
|
||||
case SQLCOM_RENAME_TABLE:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
case SQLCOM_CREATE_VIEW:
|
||||
case SQLCOM_DROP_VIEW:
|
||||
newmode= MODE_ANY;
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported sql_command=%d", thd_sql_command(thd));
|
||||
strcpy(g->Message, "CONNECT Unsupported command");
|
||||
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
|
||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||
break;
|
||||
} // endswitch newmode
|
||||
|
||||
} // endif's newmode
|
||||
|
||||
|
||||
if (xtrace)
|
||||
printf("New mode=%d\n", newmode);
|
||||
if (newmode == MODE_ERROR)
|
||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||
|
||||
// If this is the start of a new query, cleanup the previous one
|
||||
if (xp->CheckCleanup()) {
|
||||
|
|
|
@ -406,6 +406,7 @@ const char *GetValStr(OPVAL vop, bool neg);
|
|||
void position(const uchar *record); ///< required
|
||||
int info(uint); ///< required
|
||||
int extra(enum ha_extra_function operation);
|
||||
int start_stmt(THD *thd, thr_lock_type lock_type);
|
||||
int external_lock(THD *thd, int lock_type); ///< required
|
||||
int delete_all_rows(void);
|
||||
ha_rows records_in_range(uint inx, key_range *min_key,
|
||||
|
@ -435,6 +436,7 @@ const char *GetValStr(OPVAL vop, bool neg);
|
|||
|
||||
protected:
|
||||
bool check_privileges(THD *thd, PTOS options);
|
||||
MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras);
|
||||
|
||||
// Members
|
||||
static ulong num; // Tracable handler number
|
||||
|
@ -452,6 +454,7 @@ protected:
|
|||
bool valid_info; // True if xinfo is valid
|
||||
bool stop; // Used when creating index
|
||||
int indexing; // Type of indexing for CONNECT
|
||||
int locked; // Table lock
|
||||
THR_LOCK_DATA lock_data;
|
||||
|
||||
public:
|
||||
|
|
|
@ -151,7 +151,8 @@ enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
|
|||
#define NAM_LEN 128
|
||||
#endif // !0
|
||||
|
||||
enum MODE {MODE_ANY = 0, /* Unspecified mode */
|
||||
enum MODE {MODE_ERROR = -1, /* Invalid mode */
|
||||
MODE_ANY = 0, /* Unspecified mode */
|
||||
MODE_READ = 10, /* Input/Output mode */
|
||||
MODE_WRITE = 20, /* Input/Output mode */
|
||||
MODE_UPDATE = 30, /* Input/Output mode */
|
||||
|
|
|
@ -1832,8 +1832,9 @@ int XINDXS::Range(PGLOBAL g, int limit, bool incl)
|
|||
/*********************************************************************/
|
||||
if (xp->GetType() == TYPE_CONST) {
|
||||
kp->Valp->SetValue_pval(xp->GetValue(), !kp->Prefix);
|
||||
k = FastFind(Nval);
|
||||
|
||||
if ((k = FastFind(Nval)) < Num_K)
|
||||
if (k < Num_K || Op != OP_EQ)
|
||||
if (limit)
|
||||
n = (Mul) ? k : kp->Val_K;
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue