diff options
author | unknown <bar@gw.udmsearch.izhnet.ru> | 2002-02-22 15:24:42 +0400 |
---|---|---|
committer | unknown <bar@gw.udmsearch.izhnet.ru> | 2002-02-22 15:24:42 +0400 |
commit | 32a08516c974045bfc16fb30fcac18bb7ad8fbb8 (patch) | |
tree | a1157e118f45978188d5caf492b320d6302b1f93 /sql/opt_range.cc | |
parent | 3d5dc65dfd72083ed159220d03bea942094e8662 (diff) | |
download | mariadb-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.cc | 120 |
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) |