mariadb/sql/item_geofunc.h
Alexander Barkov 702166bcde WL#2649 Number-to-string conversions
added:
  include/ctype_numconv.inc
  mysql-test/include/ctype_numconv.inc
  mysql-test/r/ctype_binary.result
  mysql-test/t/ctype_binary.test
  Adding tests

modified:

  mysql-test/r/bigint.result
  mysql-test/r/case.result
  mysql-test/r/create.result
  mysql-test/r/ctype_cp1251.result
  mysql-test/r/ctype_latin1.result
  mysql-test/r/ctype_ucs.result
  mysql-test/r/func_gconcat.result
  mysql-test/r/func_str.result
  mysql-test/r/metadata.result
  mysql-test/r/ps_1general.result
  mysql-test/r/ps_2myisam.result
  mysql-test/r/ps_3innodb.result
  mysql-test/r/ps_4heap.result
  mysql-test/r/ps_5merge.result
  mysql-test/r/show_check.result
  mysql-test/r/type_datetime.result
  mysql-test/r/type_ranges.result
  mysql-test/r/union.result
  mysql-test/suite/ndb/r/ps_7ndb.result
  mysql-test/t/ctype_cp1251.test
  mysql-test/t/ctype_latin1.test
  mysql-test/t/ctype_ucs.test
  mysql-test/t/func_str.test
    Fixing tests


  @ sql/field.cc
     - Return str result using my_charset_numeric.
     - Using real multi-byte aware str_to_XXX functions
       to handle tricky charset values propely (e.g. UCS2)
  @ sql/field.h
     - Changing derivation of non-string field types to DERIVATION_NUMERIC.
     - Changing binary() for numeric/datetime fields to always
     return TRUE even if charset is not my_charset_bin. We need
     this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
     - Adding BINARY_FLAG into some fields, because it's not
     being set automatically anymore with
     "my_charset_bin to my_charset_numeric" change.
    - Changing derivation for numeric/datetime datatypes to a weaker
      value, to make "SELECT concat('string', field)" use character
      set of the string literal for the result of the function.
  @ sql/item.cc
     - Implementing generic val_str_ascii().
     - Using max_char_length() instead of direct read of max_length
       to make "tricky" charsets like UCS2 work.
       NOTE: in the future we'll possibly remove all direct reads of max_length
     - Fixing Item_num::safe_charset_converter().
       Previously it alligned binary string to
       character string (for example by adding leading 0x00
       when doing binary->UCS2 conversion). Now it just
       converts from my_charset_numbner to "tocs".
     - Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
     - Other misc changes
  @ sql/item.h
     - Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
       bit operations instead of hard-coded bit masks.
     - Addding new method DTCollation.set_numeric().
     - Adding new methods to Item.
     - Adding helper functions to make code look nicer:
       agg_item_charsets_for_string_result()
       agg_item_charsets_for_comparison()
     - Changing charset for Item_num-derived items
       from my_charset_bin to my_charset_numeric
       (which is an alias for latin1).
  @ sql/item_cmpfunc.cc
     - Using new helper functions
     - Other misc changes
  @ sql/item_cmpfunc.h
     - Fixing strcmp() to return max_length=2.
       Previously it returned 1, which was wrong,
       because it did not fit '-1'.
  @ sql/item_func.cc
     - Using new helper functions
     - Other minor changes
  @ sql/item_func.h
     - Removing unused functions
     - Adding helper functions
       agg_arg_charsets_for_string_result()
       agg_arg_charsets_for_comparison()
     - Adding set_numeric() into constructors of numeric items.
     - Using fix_length_and_charset() and fix_char_length()
       instead of direct write to max_length.
  @ sql/item_geofunc.cc
     - Changing class for Item_func_geometry_type and
       Item_func_as_wkt from Item_str_func to
       Item_str_ascii_func, to make them return UCS2 result
       properly (when character_set_connection=ucs2).
  @ sql/item_geofunc.h
     - Changing class for Item_func_geometry_type and
       Item_func_as_wkt from Item_str_func to
       Item_str_ascii_func, to make them return UCS2 result
       properly (when @@character_set_connection=ucs2).
  @ sql/item_strfunc.cc
     - Implementing Item_str_func::val_str().
     - Renaming val_str to val_str_ascii for some items,
       to make them work with UCS2 properly.
     - Using new helper functions
     - All single-argument functions that expect string
       result now call this method:
       agg_arg_charsets_for_string_result(collation, args, 1);
       This enables character set conversion to @@character_set_connection
       in case of pure numeric input.
  @ sql/item_strfunc.h
     - Introducing Item_str_ascii_func - for functions
       which return pure ASCII data, for performance purposes,
       as well as for the cases when the old implementation
       of val_str() was heavily 8-bit oriented and implementing
       a UCS2-aware version is tricky.
  @ sql/item_sum.cc
     - Using new helper functions.
  @ sql/item_timefunc.cc
     - Using my_charset_numeric instead of my_charset_bin.
     - Using fix_char_length(), fix_length_and_charset()
       and fix_length_and_charset_datetime()
       instead of direct write to max_length.
     - Using tricky-charset aware function str_to_time_with_warn()
  @ sql/item_timefunc.h
     - Using new helper functions for charset and length initialization.
     - Changing base class for Item_func_get_format() to make
       it return UCS2 properly (when character_set_connection=ucs2).
  @ sql/item_xmlfunc.cc
     - Using new helper function
  @ sql/my_decimal.cc
     - Adding a new DECIMAL to CHAR converter
       with real multibyte support (e.g. UCS2)

  @ sql/mysql_priv.h
     - Introducing a new derivation level for numeric/datetime data types.
     - Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
     - Adding prototypes for str_set_decimal()
     - Adding prototypes for character-set aware str_to_xxx() functions.
  @ sql/protocol.cc
     - Changing charsetnr to "binary" client-side metadata for
       numeric/datetime data types.
  @ sql/time.cc
     - Adding to_ascii() helper function, to convert a string
       in any character set to ascii representation. In the
       future can be extended to understand digits written
       in various non-Latin word scripts.
     - Adding real multy-byte character set aware versions for str_to_XXXX,
       to make these these type of queries work correct:
         INSERT INTO t1 SET datetime_column=ucs2_expression;
   @  strings/ctype-ucs2.c
     - endptr was not calculated correctly. INSERTing of UCS2
       values into numeric columns returned warnings about
       truncated wrong data.
2010-02-11 08:17:25 +04:00

393 lines
10 KiB
C++

#ifndef ITEM_GEOFUNC_INCLUDED
#define ITEM_GEOFUNC_INCLUDED
/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines all spatial functions */
#ifdef HAVE_SPATIAL
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
class Item_geometry_func: public Item_str_func
{
public:
Item_geometry_func() :Item_str_func() {}
Item_geometry_func(Item *a) :Item_str_func(a) {}
Item_geometry_func(Item *a,Item *b) :Item_str_func(a,b) {}
Item_geometry_func(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
Item_geometry_func(List<Item> &list) :Item_str_func(list) {}
void fix_length_and_dec();
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
Field *tmp_table_field(TABLE *t_arg);
bool is_null() { (void) val_int(); return null_value; }
};
class Item_func_geometry_from_text: public Item_geometry_func
{
public:
Item_func_geometry_from_text(Item *a) :Item_geometry_func(a) {}
Item_func_geometry_from_text(Item *a, Item *srid) :Item_geometry_func(a, srid) {}
const char *func_name() const { return "geometryfromtext"; }
String *val_str(String *);
};
class Item_func_geometry_from_wkb: public Item_geometry_func
{
public:
Item_func_geometry_from_wkb(Item *a): Item_geometry_func(a) {}
Item_func_geometry_from_wkb(Item *a, Item *srid): Item_geometry_func(a, srid) {}
const char *func_name() const { return "geometryfromwkb"; }
String *val_str(String *);
};
class Item_func_as_wkt: public Item_str_ascii_func
{
public:
Item_func_as_wkt(Item *a): Item_str_ascii_func(a) {}
const char *func_name() const { return "astext"; }
String *val_str_ascii(String *);
void fix_length_and_dec();
};
class Item_func_as_wkb: public Item_geometry_func
{
public:
Item_func_as_wkb(Item *a): Item_geometry_func(a) {}
const char *func_name() const { return "aswkb"; }
String *val_str(String *);
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
};
class Item_func_geometry_type: public Item_str_ascii_func
{
public:
Item_func_geometry_type(Item *a): Item_str_ascii_func(a) {}
String *val_str_ascii(String *);
const char *func_name() const { return "geometrytype"; }
void fix_length_and_dec()
{
// "GeometryCollection" is the longest
fix_length_and_charset(20, default_charset());
maybe_null= 1;
};
};
class Item_func_centroid: public Item_geometry_func
{
public:
Item_func_centroid(Item *a): Item_geometry_func(a) {}
const char *func_name() const { return "centroid"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
};
class Item_func_envelope: public Item_geometry_func
{
public:
Item_func_envelope(Item *a): Item_geometry_func(a) {}
const char *func_name() const { return "envelope"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
};
class Item_func_point: public Item_geometry_func
{
public:
Item_func_point(Item *a, Item *b): Item_geometry_func(a, b) {}
Item_func_point(Item *a, Item *b, Item *srid): Item_geometry_func(a, b, srid) {}
const char *func_name() const { return "point"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
};
class Item_func_spatial_decomp: public Item_geometry_func
{
enum Functype decomp_func;
public:
Item_func_spatial_decomp(Item *a, Item_func::Functype ft) :
Item_geometry_func(a) { decomp_func = ft; }
const char *func_name() const
{
switch (decomp_func)
{
case SP_STARTPOINT:
return "startpoint";
case SP_ENDPOINT:
return "endpoint";
case SP_EXTERIORRING:
return "exteriorring";
default:
DBUG_ASSERT(0); // Should never happened
return "spatial_decomp_unknown";
}
}
String *val_str(String *);
};
class Item_func_spatial_decomp_n: public Item_geometry_func
{
enum Functype decomp_func_n;
public:
Item_func_spatial_decomp_n(Item *a, Item *b, Item_func::Functype ft):
Item_geometry_func(a, b) { decomp_func_n = ft; }
const char *func_name() const
{
switch (decomp_func_n)
{
case SP_POINTN:
return "pointn";
case SP_GEOMETRYN:
return "geometryn";
case SP_INTERIORRINGN:
return "interiorringn";
default:
DBUG_ASSERT(0); // Should never happened
return "spatial_decomp_n_unknown";
}
}
String *val_str(String *);
};
class Item_func_spatial_collection: public Item_geometry_func
{
String tmp_value;
enum Geometry::wkbType coll_type;
enum Geometry::wkbType item_type;
public:
Item_func_spatial_collection(
List<Item> &list, enum Geometry::wkbType ct, enum Geometry::wkbType it):
Item_geometry_func(list)
{
coll_type=ct;
item_type=it;
}
String *val_str(String *);
const char *func_name() const { return "multipoint"; }
};
/*
Spatial relations
*/
class Item_func_spatial_rel: public Item_bool_func2
{
enum Functype spatial_rel;
public:
Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel) :
Item_bool_func2(a,b) { spatial_rel = sp_rel; }
longlong val_int();
enum Functype functype() const
{
switch (spatial_rel) {
case SP_CONTAINS_FUNC:
return SP_WITHIN_FUNC;
case SP_WITHIN_FUNC:
return SP_CONTAINS_FUNC;
default:
return spatial_rel;
}
}
enum Functype rev_functype() const { return spatial_rel; }
const char *func_name() const
{
switch (spatial_rel) {
case SP_CONTAINS_FUNC:
return "contains";
case SP_WITHIN_FUNC:
return "within";
case SP_EQUALS_FUNC:
return "equals";
case SP_DISJOINT_FUNC:
return "disjoint";
case SP_INTERSECTS_FUNC:
return "intersects";
case SP_TOUCHES_FUNC:
return "touches";
case SP_CROSSES_FUNC:
return "crosses";
case SP_OVERLAPS_FUNC:
return "overlaps";
default:
DBUG_ASSERT(0); // Should never happened
return "sp_unknown";
}
}
virtual inline void print(String *str, enum_query_type query_type)
{
Item_func::print(str, query_type);
}
void fix_length_and_dec() { maybe_null= 1; }
bool is_null() { (void) val_int(); return null_value; }
};
class Item_func_isempty: public Item_bool_func
{
public:
Item_func_isempty(Item *a): Item_bool_func(a) {}
longlong val_int();
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
const char *func_name() const { return "isempty"; }
void fix_length_and_dec() { maybe_null= 1; }
};
class Item_func_issimple: public Item_bool_func
{
public:
Item_func_issimple(Item *a): Item_bool_func(a) {}
longlong val_int();
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
const char *func_name() const { return "issimple"; }
void fix_length_and_dec() { maybe_null= 1; }
};
class Item_func_isclosed: public Item_bool_func
{
public:
Item_func_isclosed(Item *a): Item_bool_func(a) {}
longlong val_int();
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
const char *func_name() const { return "isclosed"; }
void fix_length_and_dec() { maybe_null= 1; }
};
class Item_func_dimension: public Item_int_func
{
String value;
public:
Item_func_dimension(Item *a): Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "dimension"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
};
class Item_func_x: public Item_real_func
{
String value;
public:
Item_func_x(Item *a): Item_real_func(a) {}
double val_real();
const char *func_name() const { return "x"; }
void fix_length_and_dec()
{
Item_real_func::fix_length_and_dec();
maybe_null= 1;
}
};
class Item_func_y: public Item_real_func
{
String value;
public:
Item_func_y(Item *a): Item_real_func(a) {}
double val_real();
const char *func_name() const { return "y"; }
void fix_length_and_dec()
{
Item_real_func::fix_length_and_dec();
maybe_null= 1;
}
};
class Item_func_numgeometries: public Item_int_func
{
String value;
public:
Item_func_numgeometries(Item *a): Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "numgeometries"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
};
class Item_func_numinteriorring: public Item_int_func
{
String value;
public:
Item_func_numinteriorring(Item *a): Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "numinteriorrings"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
};
class Item_func_numpoints: public Item_int_func
{
String value;
public:
Item_func_numpoints(Item *a): Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "numpoints"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
};
class Item_func_area: public Item_real_func
{
String value;
public:
Item_func_area(Item *a): Item_real_func(a) {}
double val_real();
const char *func_name() const { return "area"; }
void fix_length_and_dec()
{
Item_real_func::fix_length_and_dec();
maybe_null= 1;
}
};
class Item_func_glength: public Item_real_func
{
String value;
public:
Item_func_glength(Item *a): Item_real_func(a) {}
double val_real();
const char *func_name() const { return "glength"; }
void fix_length_and_dec()
{
Item_real_func::fix_length_and_dec();
maybe_null= 1;
}
};
class Item_func_srid: public Item_int_func
{
String value;
public:
Item_func_srid(Item *a): Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "srid"; }
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
};
#define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor
#else /*HAVE_SPATIAL*/
#define GEOM_NEW(thd, obj_constructor) NULL
#endif
#endif /* ITEM_GEOFUNC_INCLUDED */