Commit 4884ba5e authored by Andrew McDonnell's avatar Andrew McDonnell

Implement latch VARCHAR()- table structure - retain SHORTINT backwards...

Implement latch VARCHAR()- table structure - retain SHORTINT backwards compatibility. Passes test for b/compat
parent 44222abf
...@@ -47,8 +47,14 @@ ...@@ -47,8 +47,14 @@
using namespace open_query; using namespace open_query;
// Allow int latch for now
#define RETAIN_INT_LATCH_COMPATIBILITY
#define MIN_VARCHAR_LATCH_LEN 32
// Table of varchar latch operations. // Table of varchar latch operations.
// In the future this needs to be refactactored to somewhere else // In the future this needs to be refactactored to live somewhere else
struct oqgraph_latch_op_table { const char *key; int latch; }; struct oqgraph_latch_op_table { const char *key; int latch; };
static const oqgraph_latch_op_table latch_ops_table[] = { static const oqgraph_latch_op_table latch_ops_table[] = {
{ "no_search", oqgraph::NO_SEARCH } , { "no_search", oqgraph::NO_SEARCH } ,
...@@ -198,9 +204,10 @@ static int error_code(int res) ...@@ -198,9 +204,10 @@ static int error_code(int res)
The latch may be a varchar of any length, however if it is too short, The latch may be a varchar of any length, however if it is too short,
then some of the OQGRAPH graph operations will not be able to be executed. then some of the OQGRAPH graph operations will not be able to be executed.
A size of 32 seems reasonable at this point in time.
CREATE TABLE foo ( CREATE TABLE foo (
latch VARCHAR(255) NULL, latch VARCHAR(32) NULL,
origid BIGINT UNSIGNED NULL, origid BIGINT UNSIGNED NULL,
destid BIGINT UNSIGNED NULL, destid BIGINT UNSIGNED NULL,
weight DOUBLE NULL, weight DOUBLE NULL,
...@@ -214,11 +221,13 @@ static int error_code(int res) ...@@ -214,11 +221,13 @@ static int error_code(int res)
DESTID=tgt_id DESTID=tgt_id
*/ */
static int oqgraph_check_table_structure (TABLE *table_arg) int ha_oqgraph::oqgraph_check_table_structure (TABLE *table_arg)
{ {
// Changed from static so we can do decent error reporting.
int i; int i;
struct { const char *colname; int coltype; } skel[] = { struct { const char *colname; int coltype; } skel[] = {
{ "latch" , MYSQL_TYPE_STRING }, { "latch" , MYSQL_TYPE_VARCHAR },
{ "origid", MYSQL_TYPE_LONGLONG }, { "origid", MYSQL_TYPE_LONGLONG },
{ "destid", MYSQL_TYPE_LONGLONG }, { "destid", MYSQL_TYPE_LONGLONG },
{ "weight", MYSQL_TYPE_DOUBLE }, { "weight", MYSQL_TYPE_DOUBLE },
...@@ -227,28 +236,75 @@ static int oqgraph_check_table_structure (TABLE *table_arg) ...@@ -227,28 +236,75 @@ static int oqgraph_check_table_structure (TABLE *table_arg)
{ NULL , 0} { NULL , 0}
}; };
DBUG_ENTER("ha_oqgraph::table_structure_ok"); DBUG_ENTER("oqgraph_check_table_structure");
#ifdef RETAIN_INT_LATCH_COMPATIBILITY
DBUG_PRINT( "oq-debug", ("With integer latch compatibility mode."));
#endif
DBUG_PRINT( "oq-debug", ("Checking structure."));
Field **field= table_arg->field; Field **field= table_arg->field;
for (i= 0; *field && skel[i].colname; i++, field++) { for (i= 0; *field && skel[i].colname; i++, field++) {
DBUG_PRINT( "oq-debug", ("Column %d: name='%s', expected '%s'; type=%d, expected %d.", i, (*field)->field_name, skel[i].colname, (*field)->type(), skel[i].coltype));
bool badColumn = false;
bool isLatchColumn = strcmp(skel[i].colname, "latch")==0;
bool isStringLatch = true;
#ifdef RETAIN_INT_LATCH_COMPATIBILITY
if (isLatchColumn && ((*field)->type() == MYSQL_TYPE_SHORT))
{
isStringLatch = false;
/* Make a warning */
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX, ER(ER_WARN_DEPRECATED_SYNTAX),
"latch SMALLINT UNSIGNED NULL", "'latch VARCHAR(32) NULL'");
} else
#endif
/* Check Column Type */ /* Check Column Type */
if ((*field)->type() != skel[i].coltype) if ((*field)->type() != skel[i].coltype) {
DBUG_RETURN(-1); badColumn = true;
if (skel[i].coltype != MYSQL_TYPE_DOUBLE) { push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Column %d is wrong type.", i);
}
// TODO: check latch size >= MIN_VARCHAR_LATCH_LEN
if (!badColumn) if (skel[i].coltype != MYSQL_TYPE_DOUBLE && (!isLatchColumn || !isStringLatch)) {
/* Check Is UNSIGNED */ /* Check Is UNSIGNED */
if (!((*field)->flags & UNSIGNED_FLAG )) if ( (!((*field)->flags & UNSIGNED_FLAG ))) {
DBUG_RETURN(-1); badColumn = true;
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Column %d must be UNSIGNED.", i);
}
} }
/* Check THAT NOT NULL isn't set */ /* Check THAT NOT NULL isn't set */
if ((*field)->flags & NOT_NULL_FLAG) if (!badColumn) if ((*field)->flags & NOT_NULL_FLAG) {
DBUG_RETURN(-1); badColumn = true;
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Column %d must be NULL.", i);
}
/* Check the column name */ /* Check the column name */
if (strcmp(skel[i].colname,(*field)->field_name)) if (!badColumn) if (strcmp(skel[i].colname,(*field)->field_name)) {
badColumn = true;
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Column %d must be named '%s'.", i, skel[i].colname);
}
if (badColumn) {
DBUG_RETURN(-1); DBUG_RETURN(-1);
}
} }
if (skel[i].colname || *field || !table_arg->key_info || !table_arg->s->keys) if (skel[i].colname) {
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Not enough columns.");
DBUG_RETURN(-1); DBUG_RETURN(-1);
}
if (*field) {
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Too many columns.");
DBUG_RETURN(-1);
}
if (!table_arg->key_info || !table_arg->s->keys) {
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "No vaild key specification.");
DBUG_RETURN(-1);
}
DBUG_PRINT( "oq-debug", ("Checking keys."));
KEY *key= table_arg->key_info; KEY *key= table_arg->key_info;
for (uint i= 0; i < table_arg->s->keys; ++i, ++key) for (uint i= 0; i < table_arg->s->keys; ++i, ++key)
...@@ -256,8 +312,10 @@ static int oqgraph_check_table_structure (TABLE *table_arg) ...@@ -256,8 +312,10 @@ static int oqgraph_check_table_structure (TABLE *table_arg)
Field **field= table_arg->field; Field **field= table_arg->field;
/* check that the first key part is the latch and it is a hash key */ /* check that the first key part is the latch and it is a hash key */
if (!(field[0] == key->key_part[0].field && if (!(field[0] == key->key_part[0].field &&
HA_KEY_ALG_HASH == key->algorithm)) HA_KEY_ALG_HASH == key->algorithm)) {
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Incorrect keys algorithm on key %d.", i);
DBUG_RETURN(-1); DBUG_RETURN(-1);
}
if (key->key_parts == 3) if (key->key_parts == 3)
{ {
/* KEY (latch, origid, destid) USING HASH */ /* KEY (latch, origid, destid) USING HASH */
...@@ -266,10 +324,15 @@ static int oqgraph_check_table_structure (TABLE *table_arg) ...@@ -266,10 +324,15 @@ static int oqgraph_check_table_structure (TABLE *table_arg)
field[2] == key->key_part[2].field) && field[2] == key->key_part[2].field) &&
!(field[1] == key->key_part[2].field && !(field[1] == key->key_part[2].field &&
field[2] == key->key_part[1].field)) field[2] == key->key_part[1].field))
{
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Keys parts mismatch on key %d.", i);
DBUG_RETURN(-1); DBUG_RETURN(-1);
}
} }
else else {
push_warning_printf( current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, "Too many key parts on key %d.", i);
DBUG_RETURN(-1); DBUG_RETURN(-1);
}
} }
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -687,15 +750,22 @@ int ha_oqgraph::index_read_idx(byte * buf, uint index, const byte * key, ...@@ -687,15 +750,22 @@ int ha_oqgraph::index_read_idx(byte * buf, uint index, const byte * key,
if (!field[0]->is_null()) if (!field[0]->is_null())
{ {
//latch= (int) field[0]->val_int(); #ifdef RETAIN_INT_LATCH_COMPATIBILITY
String value; if (field[0]->type() == MYSQL_TYPE_SHORT) {
field[0]->val_str(&value, &value); latch= (int) field[0]->val_int();
if (!parse_latch_string_to_legacy_int(value, latch)) { } else
// Invalid, so warn & fail #endif
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WRONG_ARGUMENTS, ER(ER_WRONG_ARGUMENTS), "OQGRAPH latch"); {
table->status = STATUS_NOT_FOUND; String value;
return error_code(oqgraph::NO_MORE_DATA); field[0]->val_str(&value, &value);
if (!parse_latch_string_to_legacy_int(value, latch)) {
// Invalid, so warn & fail
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WRONG_ARGUMENTS, ER(ER_WRONG_ARGUMENTS), "OQGRAPH latch");
table->status = STATUS_NOT_FOUND;
return error_code(oqgraph::NO_MORE_DATA);
}
} }
DBUG_PRINT( "oq-debug", ("latch:%d", latch));
latchp= &latch; latchp= &latch;
} }
...@@ -900,7 +970,10 @@ ha_rows ha_oqgraph::records_in_range(uint inx, key_range *min_key, ...@@ -900,7 +970,10 @@ ha_rows ha_oqgraph::records_in_range(uint inx, key_range *min_key,
if (min_key->length == key->key_part[0].store_length) if (min_key->length == key->key_part[0].store_length)
{ {
// If latch is not null and equals 0, return # nodes // If latch is not null and equals 0, return # nodes
// This assertion is not valid anymore if we are using a VARCHAR latch.
DBUG_ASSERT(key->key_part[0].store_length == 3); DBUG_ASSERT(key->key_part[0].store_length == 3);
if (key->key_part[0].null_bit && !min_key->key[0] && if (key->key_part[0].null_bit && !min_key->key[0] &&
!min_key->key[1] && !min_key->key[2]) !min_key->key[1] && !min_key->key[2])
return graph->vertices_count(); return graph->vertices_count();
...@@ -926,14 +999,15 @@ int ha_oqgraph::create(const char *name, TABLE *table_arg, ...@@ -926,14 +999,15 @@ int ha_oqgraph::create(const char *name, TABLE *table_arg,
oqgraph_table_option_struct *options= oqgraph_table_option_struct *options=
reinterpret_cast<oqgraph_table_option_struct*>(table_arg->s->option_struct); reinterpret_cast<oqgraph_table_option_struct*>(table_arg->s->option_struct);
DBUG_ENTER("ha_oqgraph::create");
DBUG_PRINT( "oq-debug", ("create(name=%s)", name)); DBUG_PRINT( "oq-debug", ("create(name=%s)", name));
if (int res = oqgraph_check_table_structure(table_arg)) {
if (int res = oqgraph_check_table_structure(table_arg)) DBUG_RETURN(HA_WRONG_CREATE_OPTION);
return error_code(res); }
(void)(options); (void)(options);
return 0; DBUG_RETURN(0);
} }
......
...@@ -110,6 +110,8 @@ public: ...@@ -110,6 +110,8 @@ public:
void fprint_error(const char* fmt, ...); void fprint_error(const char* fmt, ...);
private: private:
int oqgraph_check_table_structure (TABLE *table_arg);
void update_key_stats(); void update_key_stats();
String error_message; String error_message;
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment