summaryrefslogtreecommitdiff
path: root/sql/ha_ndbcluster.cc
diff options
context:
space:
mode:
authorunknown <joreland@mysql.com>2004-12-06 14:52:31 +0100
committerunknown <joreland@mysql.com>2004-12-06 14:52:31 +0100
commitbf0b3493d695ec32814017be1f2da059b65982c0 (patch)
tree3071885324d9cba2e6369bdea65d4d7f3c56ab03 /sql/ha_ndbcluster.cc
parenteb05d78dcb8074a5dfceedf8c86681531fc3bfbe (diff)
parentb1f4a482f4545999d6210aabdc2c0a80ee574374 (diff)
downloadmariadb-git-bf0b3493d695ec32814017be1f2da059b65982c0.tar.gz
Merge mysql.com:/home/jonas/src/mysql-4.1-fix
into mysql.com:/home/jonas/src/wl1744 BitKeeper/etc/logging_ok: auto-union configure.in: Auto merged ndb/include/Makefile.am: Auto merged ndb/src/common/mgmcommon/ConfigRetriever.cpp: Auto merged ndb/src/common/util/version.c: Auto merged ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Auto merged ndb/src/kernel/blocks/dbdict/Dbdict.hpp: Auto merged ndb/src/kernel/blocks/dbdih/Dbdih.hpp: Auto merged ndb/src/kernel/blocks/dbdih/DbdihMain.cpp: Auto merged ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: Auto merged ndb/src/mgmsrv/main.cpp: Auto merged ndb/src/ndbapi/NdbConnection.cpp: Auto merged sql/ha_ndbcluster.cc: Auto merged
Diffstat (limited to 'sql/ha_ndbcluster.cc')
-rw-r--r--sql/ha_ndbcluster.cc119
1 files changed, 94 insertions, 25 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 331988f87c8..fe1a41f4ae2 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -109,7 +109,7 @@ static const err_code_mapping err_map[]=
{
{ 626, HA_ERR_KEY_NOT_FOUND },
{ 630, HA_ERR_FOUND_DUPP_KEY },
- { 893, HA_ERR_FOUND_DUPP_UNIQUE },
+ { 893, HA_ERR_FOUND_DUPP_KEY }, // Unique constraint
{ 721, HA_ERR_TABLE_EXIST },
{ 4244, HA_ERR_TABLE_EXIST },
@@ -1018,7 +1018,8 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
{
Field *field= table->field[i];
if ((thd->query_id == field->query_id) ||
- m_retrieve_all_fields)
+ m_retrieve_all_fields ||
+ (field->flags & PRI_KEY_FLAG) && m_retrieve_primary_key)
{
if (get_ndb_value(op, field, i, buf))
ERR_RETURN(trans->getNdbError());
@@ -1029,7 +1030,6 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
m_value[i].ptr= NULL;
}
}
-
if (execute_no_commit_ie(this,trans) != 0)
{
table->status= STATUS_NOT_FOUND;
@@ -1093,6 +1093,34 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data)
DBUG_RETURN(0);
}
+/*
+ Peek to check if a particular row already exists
+*/
+
+int ha_ndbcluster::peek_row()
+{
+ NdbConnection *trans= m_active_trans;
+ NdbOperation *op;
+ THD *thd= current_thd;
+ DBUG_ENTER("peek_row");
+
+ NdbOperation::LockMode lm=
+ (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
+ if (!(op= trans->getNdbOperation((const NDBTAB *) m_table)) ||
+ op->readTuple(lm) != 0)
+ ERR_RETURN(trans->getNdbError());
+
+ int res;
+ if ((res= set_primary_key(op)))
+ ERR_RETURN(trans->getNdbError());
+
+ if (execute_no_commit_ie(this,trans) != 0)
+ {
+ table->status= STATUS_NOT_FOUND;
+ DBUG_RETURN(ndb_err(trans));
+ }
+ DBUG_RETURN(0);
+}
/*
Read one record from NDB using unique secondary index
@@ -1128,9 +1156,10 @@ int ha_ndbcluster::unique_index_read(const byte *key,
for (i= 0; key_part != end; key_part++, i++)
{
- if (set_ndb_key(op, key_part->field, i, key_ptr))
+ if (set_ndb_key(op, key_part->field, i,
+ key_part->null_bit ? key_ptr + 1 : key_ptr))
ERR_RETURN(trans->getNdbError());
- key_ptr+= key_part->length;
+ key_ptr+= key_part->store_length;
}
// Get non-index attribute(s)
@@ -1138,7 +1167,7 @@ int ha_ndbcluster::unique_index_read(const byte *key,
{
Field *field= table->field[i];
if ((thd->query_id == field->query_id) ||
- (field->flags & PRI_KEY_FLAG))
+ (field->flags & PRI_KEY_FLAG)) // && m_retrieve_primary_key ??
{
if (get_ndb_value(op, field, i, buf))
ERR_RETURN(op->getNdbError());
@@ -1566,7 +1595,7 @@ int ha_ndbcluster::filtered_scan(const byte *key, uint key_len,
Field* field= key_part->field;
uint ndb_fieldnr= key_part->fieldnr-1;
DBUG_PRINT("key_part", ("fieldnr: %d", ndb_fieldnr));
- // const NDBCOL *col= tab->getColumn(ndb_fieldnr);
+ //const NDBCOL *col= ((const NDBTAB *) m_table)->getColumn(ndb_fieldnr);
uint32 field_len= field->pack_length();
DBUG_DUMP("key", (char*)key, field_len);
@@ -1635,9 +1664,17 @@ int ha_ndbcluster::write_row(byte *record)
int res;
DBUG_ENTER("write_row");
- if(m_ignore_dup_key_not_supported)
+ if(m_ignore_dup_key && table->primary_key != MAX_KEY)
{
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ int peek_res= peek_row();
+
+ if (!peek_res)
+ {
+ m_dupkey= table->primary_key;
+ DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY);
+ }
+ if (peek_res != HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(peek_res);
}
statistic_increment(ha_write_count,&LOCK_status);
@@ -1791,7 +1828,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
NdbOperation *op;
uint i;
DBUG_ENTER("update_row");
-
+
statistic_increment(ha_update_count,&LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
@@ -2144,22 +2181,19 @@ void ha_ndbcluster::print_results()
}
case NdbDictionary::Column::Decimal: {
char *value= field->ptr;
-
fprintf(DBUG_FILE, "Decimal\t'%-*s'", field->pack_length(), value);
break;
}
case NdbDictionary::Column::Char:{
- char buf[field->pack_length()+1];
- char *value= (char *) field->ptr;
- snprintf(buf, field->pack_length(), "%s", value);
- fprintf(DBUG_FILE, "Char\t'%s'", buf);
+ const char *value= (char *) field->ptr;
+ fprintf(DBUG_FILE, "Char\t'%.*s'", field->pack_length(), value);
break;
}
case NdbDictionary::Column::Varchar:
case NdbDictionary::Column::Binary:
case NdbDictionary::Column::Varbinary: {
- char *value= (char *) field->ptr;
- fprintf(DBUG_FILE, "'%s'", value);
+ const char *value= (char *) field->ptr;
+ fprintf(DBUG_FILE, "Var\t'%.*s'", field->pack_length(), value);
break;
}
case NdbDictionary::Column::Datetime: {
@@ -2210,6 +2244,28 @@ int ha_ndbcluster::index_end()
DBUG_RETURN(close_scan());
}
+/**
+ * Check if key contains null
+ */
+static
+int
+check_null_in_key(const KEY* key_info, const byte *key, uint key_len)
+{
+ KEY_PART_INFO *curr_part, *end_part;
+ const byte* end_ptr = key + key_len;
+ curr_part= key_info->key_part;
+ end_part= curr_part + key_info->key_parts;
+
+
+ for (; curr_part != end_part && key < end_ptr; curr_part++)
+ {
+ if(curr_part->null_bit && *key)
+ return 1;
+
+ key += curr_part->store_length;
+ }
+ return 0;
+}
int ha_ndbcluster::index_read(byte *buf,
const byte *key, uint key_len,
@@ -2227,6 +2283,8 @@ int ha_ndbcluster::index_read(byte *buf,
case PRIMARY_KEY_INDEX:
if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len)
{
+ if(m_active_cursor && (error= close_scan()))
+ DBUG_RETURN(error);
DBUG_RETURN(pk_read(key, key_len, buf));
}
else if (type == PRIMARY_KEY_INDEX)
@@ -2236,8 +2294,11 @@ int ha_ndbcluster::index_read(byte *buf,
break;
case UNIQUE_ORDERED_INDEX:
case UNIQUE_INDEX:
- if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len)
+ if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len &&
+ !check_null_in_key(key_info, key, key_len))
{
+ if(m_active_cursor && (error= close_scan()))
+ DBUG_RETURN(error);
DBUG_RETURN(unique_index_read(key, key_len, buf));
}
else if (type == UNIQUE_INDEX)
@@ -2341,6 +2402,8 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
start_key->length == key_info->key_length &&
start_key->flag == HA_READ_KEY_EXACT)
{
+ if(m_active_cursor && (error= close_scan()))
+ DBUG_RETURN(error);
error= pk_read(start_key->key, start_key->length, buf);
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
}
@@ -2348,10 +2411,12 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
case UNIQUE_ORDERED_INDEX:
case UNIQUE_INDEX:
key_info= table->key_info + active_index;
- if (start_key &&
- start_key->length == key_info->key_length &&
- start_key->flag == HA_READ_KEY_EXACT)
+ if (start_key && start_key->length == key_info->key_length &&
+ start_key->flag == HA_READ_KEY_EXACT &&
+ !check_null_in_key(key_info, start_key->key, start_key->length))
{
+ if(m_active_cursor && (error= close_scan()))
+ DBUG_RETURN(error);
error= unique_index_read(start_key->key, start_key->length, buf);
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
}
@@ -2653,15 +2718,15 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
m_use_write= TRUE;
} else
{
- if (table->keys)
- m_ignore_dup_key_not_supported= TRUE;
+ DBUG_PRINT("info", ("Ignoring duplicate key"));
+ m_ignore_dup_key= TRUE;
}
break;
case HA_EXTRA_NO_IGNORE_DUP_KEY:
DBUG_PRINT("info", ("HA_EXTRA_NO_IGNORE_DUP_KEY"));
DBUG_PRINT("info", ("Turning OFF use of write instead of insert"));
m_use_write= FALSE;
- m_ignore_dup_key_not_supported= FALSE;
+ m_ignore_dup_key= FALSE;
break;
case HA_EXTRA_RETRIEVE_ALL_COLS: /* Retrieve all columns, not just those
where field->query_id is the same as
@@ -2680,6 +2745,7 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
break;
case HA_EXTRA_RETRIEVE_PRIMARY_KEY:
DBUG_PRINT("info", ("HA_EXTRA_RETRIEVE_PRIMARY_KEY"));
+ m_retrieve_primary_key= TRUE;
break;
case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
DBUG_PRINT("info", ("HA_EXTRA_CHANGE_KEY_TO_UNIQUE"));
@@ -2942,6 +3008,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_ASSERT(m_active_trans);
// Start of transaction
m_retrieve_all_fields= FALSE;
+ m_retrieve_primary_key= FALSE;
m_ops_pending= 0;
{
NDBDICT *dict= m_ndb->getDictionary();
@@ -3034,6 +3101,7 @@ int ha_ndbcluster::start_stmt(THD *thd)
// Start of statement
m_retrieve_all_fields= FALSE;
+ m_retrieve_primary_key= FALSE;
m_ops_pending= 0;
DBUG_RETURN(error);
@@ -3640,9 +3708,10 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
HA_NO_PREFIX_CHAR_KEYS),
m_share(0),
m_use_write(FALSE),
- m_ignore_dup_key_not_supported(FALSE),
+ m_ignore_dup_key(FALSE),
m_primary_key_update(FALSE),
m_retrieve_all_fields(FALSE),
+ m_retrieve_primary_key(FALSE),
m_rows_to_insert(1),
m_rows_inserted(0),
m_bulk_insert_rows(1024),