summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <bar@gw.udmsearch.izhnet.ru>2002-02-22 15:24:42 +0400
committerunknown <bar@gw.udmsearch.izhnet.ru>2002-02-22 15:24:42 +0400
commit32a08516c974045bfc16fb30fcac18bb7ad8fbb8 (patch)
treea1157e118f45978188d5caf492b320d6302b1f93 /sql/opt_range.cc
parent3d5dc65dfd72083ed159220d03bea942094e8662 (diff)
downloadmariadb-git-32a08516c974045bfc16fb30fcac18bb7ad8fbb8.tar.gz
Added GIS extension
BitKeeper/etc/ignore: Added myisam/rt_test myisam/sp_test to the ignore list
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc120
1 files changed, 100 insertions, 20 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index c3f4c91b718..34ee34ecc79 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -172,8 +172,9 @@ public:
void store(uint length,char **min_key,uint min_key_flag,
char **max_key, uint max_key_flag)
{
- if (!(min_flag & NO_MIN_RANGE) &&
- !(min_key_flag & (NO_MIN_RANGE | NEAR_MIN)))
+ if ((min_flag & GEOM_FLAG) ||
+ (!(min_flag & NO_MIN_RANGE) &&
+ !(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
{
if (maybe_null && *min_value)
{
@@ -659,6 +660,8 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
key_parts->null_bit= key_info->key_part[part].null_bit;
if (key_parts->field->type() == FIELD_TYPE_BLOB)
key_parts->part_length+=HA_KEY_BLOB_LENGTH;
+ key_parts->image_type =
+ (key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW;
}
param.real_keynr[param.keys++]=idx;
}
@@ -676,6 +679,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
{
SEL_ARG **key,**end,**best_key=0;
+
for (idx=0,key=tree->keys, end=key+param.keys ;
key != end ;
key++,idx++)
@@ -1042,7 +1046,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
DBUG_RETURN(0);
if (maybe_null)
*str=0; // Not NULL
- field->get_key_image(str+maybe_null,key_part->part_length);
+ field->get_key_image(str+maybe_null,key_part->part_length, key_part->image_type);
if (!(tree=new SEL_ARG(field,str,str)))
DBUG_RETURN(0);
@@ -1067,6 +1071,41 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
case Item_func::GE_FUNC:
tree->max_flag=NO_MAX_RANGE;
break;
+ case Item_func::SP_EQUALS_FUNC:
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_EQUAL;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
+ case Item_func::SP_DISJOINT_FUNC:
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_DISJOINT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
+ case Item_func::SP_INTERSECTS_FUNC:
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
+ case Item_func::SP_TOUCHES_FUNC:
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
+
+ case Item_func::SP_CROSSES_FUNC:
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
+ case Item_func::SP_WITHIN_FUNC:
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_WITHIN;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
+
+ case Item_func::SP_CONTAINS_FUNC:
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_CONTAIN;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
+ case Item_func::SP_OVERLAPS_FUNC:
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
+
default:
break;
}
@@ -2187,18 +2226,30 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
!memcmp(param->min_key,param->max_key,min_key_length))
tmp=1; // Max one record
else
+ {
+ if(tmp_min_flag & GEOM_FLAG)
+ {
+ tmp=param->table->file->
+ records_in_range((int) keynr,(byte*)(param->min_key + 1),
+ min_key_length, (ha_rkey_function)(tmp_min_flag ^ GEOM_FLAG),
+ (byte *)NullS,0,HA_READ_KEY_EXACT);
+ }
+ else
+ {
tmp=param->table->file->
records_in_range((int) keynr,
(byte*) (!min_key_length ? NullS :
param->min_key),
min_key_length,
- (tmp_min_flag & NEAR_MIN ?
- HA_READ_AFTER_KEY : HA_READ_KEY_EXACT),
+ tmp_min_flag & NEAR_MIN ?
+ HA_READ_AFTER_KEY : HA_READ_KEY_EXACT,
(byte*) (!max_key_length ? NullS :
param->max_key),
max_key_length,
(tmp_max_flag & NEAR_MAX ?
HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY));
+ }
+ }
end:
if (tmp == HA_POS_ERROR) // Impossible range
return tmp;
@@ -2294,19 +2345,24 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
}
}
else
- flag=key_tree->min_flag | key_tree->max_flag;
+ {
+ flag = (key_tree->min_flag & GEOM_FLAG) ?
+ key_tree->min_flag : key_tree->min_flag | key_tree->max_flag;
+ }
/* Ensure that some part of min_key and max_key are used. If not,
regard this as no lower/upper range */
- if (tmp_min_key != param->min_key)
- flag&= ~NO_MIN_RANGE;
- else
- flag|= NO_MIN_RANGE;
- if (tmp_max_key != param->max_key)
- flag&= ~NO_MAX_RANGE;
- else
- flag|= NO_MAX_RANGE;
-
+ if((flag & GEOM_FLAG) == 0)
+ {
+ if (tmp_min_key != param->min_key)
+ flag&= ~NO_MIN_RANGE;
+ else
+ flag|= NO_MIN_RANGE;
+ if (tmp_max_key != param->max_key)
+ flag&= ~NO_MAX_RANGE;
+ else
+ flag|= NO_MAX_RANGE;
+ }
if (flag == 0)
{
uint length= (uint) (tmp_min_key - param->min_key);
@@ -2439,13 +2495,19 @@ int QUICK_SELECT::get_next()
int result;
if (range)
{ // Already read through key
- result=((range->flag & EQ_RANGE) ?
+/* result=((range->flag & EQ_RANGE) ?
file->index_next_same(record, (byte*) range->min_key,
range->min_length) :
file->index_next(record));
+*/
+ result=((range->flag & (EQ_RANGE | GEOM_FLAG) ) ?
+ file->index_next_same(record, (byte*) range->min_key,
+ range->min_length) :
+ file->index_next(record));
+
if (!result)
{
- if (!cmp_next(*it.ref()))
+ if ((range->flag & GEOM_FLAG) || !cmp_next(*it.ref()))
DBUG_RETURN(0);
}
else if (result != HA_ERR_END_OF_FILE)
@@ -2454,6 +2516,23 @@ int QUICK_SELECT::get_next()
if (!(range=it++))
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
+
+ if(range->flag & GEOM_FLAG)
+ {
+ if ((result = file->index_read(record,
+ (byte*) (range->min_key + ((range->flag & GEOM_FLAG) > 0)),
+ range->min_length,
+ (ha_rkey_function)(range->flag ^ GEOM_FLAG))))
+
+ {
+ if (result != HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(result);
+ range=0; // Not found, to next range
+ continue;
+ }
+ DBUG_RETURN(0);
+ }
+
if (range->flag & NO_MIN_RANGE) // Read first record
{
int error;
@@ -2464,13 +2543,14 @@ int QUICK_SELECT::get_next()
range=0; // No matching records; go to next range
continue;
}
- if ((result = file->index_read(record,(byte*) range->min_key,
+ if ((result = file->index_read(record,
+ (byte*) (range->min_key + ((range->flag & GEOM_FLAG) > 0)),
range->min_length,
- ((range->flag & NEAR_MIN) ?
+ (range->flag & NEAR_MIN) ?
HA_READ_AFTER_KEY:
(range->flag & EQ_RANGE) ?
HA_READ_KEY_EXACT :
- HA_READ_KEY_OR_NEXT))))
+ HA_READ_KEY_OR_NEXT)))
{
if (result != HA_ERR_KEY_NOT_FOUND)