Commit graph

2443 commits

Author SHA1 Message Date
Alexander Barkov
cd32f84214 MDEV-12770 Add Type_handler::decimal_precision() + MDEV-12769
This patch for MDEV-12770 is also fixing:

MDEV-12769 Arithmetic operators with temporal types create excessive column types
2017-05-10 08:30:56 +04:00
Alexander Barkov
da63db1e3b MDEV-12719 Determine Item::result_type() from Item::type_handler() 2017-05-07 19:29:23 +04:00
Alexander Barkov
4e9022b48b MDEV-12718 Determine Item::cmp_type() from Item::type_handler() 2017-05-07 09:12:54 +04:00
Alexander Barkov
c898de84b7 MDEV-12714 Determine Item::field_type() from Item::type_handler() 2017-05-06 20:44:05 +04:00
Alexander Barkov
46239f29c6 MDEV-12713 Define virtual type_handler() for all Item classes 2017-05-06 19:12:59 +04:00
Alexander Barkov
5a644e177f Adding "const" qualifier to Item::cols(), and to the "Item *cmp" parameter to Type_handler::make_const_item_for_comparison() 2017-05-06 15:05:59 +04:00
Alexander Barkov
380ec90905 MDEV-12710 Fix Item_cache constructors to accept Type_handler instead of enum_field_types 2017-05-06 13:34:16 +04:00
Alexander Barkov
26fa7232cf MDEV-12707 Split resolve_const_item() into virtual methods in Type_handler 2017-05-06 00:04:15 +04:00
Alexander Barkov
ac53b49b1b Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext 2017-05-05 16:12:54 +04:00
Alexander Barkov
db0917f68f MDEV-12696 Crash with LOAD XML and non-updatable VIEW column 2017-05-05 11:05:55 +04:00
Alexander Barkov
583b68e899 MDEV-12560, MDEV-12665 - geometry type not preserved in hybrid functions and UNION
This is a join patch fixing these two bugs:
MDEV-12560 Wrong data type for SELECT NULL UNION SELECT Point(1,1)
MDEV-12665 Hybrid functions do not preserve geometry type
2017-05-05 07:23:16 +04:00
Alexander Barkov
fe127562e2 MDEV-12687 Split Item::send() into virtual method in Type_handler 2017-05-04 16:05:21 +04:00
Alexander Barkov
ae5b31fe52 A cleanup for MDEV-12619 UNION creates excessive integer column types for integer literals
Fixing result set metadata for Item_int to match type_handler(),
i.e. MYSQL_TYPE_LONG for small numbers and MYSQL_TYPE_LONGLONG for big numbers.
2017-05-04 13:17:12 +04:00
Alexander Barkov
85b73e2254 MDEV-12656 Crash in CREATE..SELECT..UNION with a ENUM column and NULL 2017-05-02 11:39:20 +04:00
Alexander Barkov
50b70e765b MDEV-12655 Move Item_func::count_xxx_length() to Type_std_attributes 2017-05-02 07:49:06 +04:00
Alexander Barkov
c67971a8a3 MDEV-12649 Add Type_handler::Item_save_in_value 2017-04-30 22:50:37 +04:00
Sergei Golubchik
5ccaabe962 MDEV-10355 Weird error message upon CREATE TABLE with DEFAULT
post-fix for 0b52b28b91

* restore EXPLAIN output
* remove redundant code
2017-04-30 14:58:11 +02:00
Alexander Barkov
7a19c59c00 MDEV-9395 Add Type_handler::Item_decimal_scale() and Item_divisor_precision_increment() 2017-04-29 21:34:57 +04:00
Alexander Barkov
ea18b11235 MDEV-12619 UNION creates excessive integer column types for integer literals 2017-04-28 16:27:55 +04:00
Alexander Barkov
441349aa06 MDEV-12588 Add Type_handler::type_handler_for_tmp_table() and Type_handler::type_handler_for_union()
1. Implementing the task according to the description:

a. Adding Type_handler::type_handler_for_tmp_table().
b. Adding Type_handler::type_handler_for_union_table.
c. Adding helper methods Type_handler::varstring_type_handler(const Item*),
   Type_handler::blob_type_handler(const Item*)
d. Removing Item::make_string_field() and
   Item_func_group_concat::make_string_field().
   They are not needed any more.
e. Simplifying Item::tmp_table_field_from_field_type() to just two lines.
f. Renaming Item_type_holder::make_field_by_type() and implementing
   virtual Item_type_holder::create_tmp_field() instead.
   The new implementation is also as simple as two lines.
g. Adding a new virtual method Type_all_attributes::get_typelib(),
   to access to TYPELIB definitions for ENUM and SET columns.
h. Simplifying the code branch for TIME_RESULT, DECIMAL_RESULT, STRING_RESULT
   in Item::create_tmp_field(). It's now just one line.
i. Implementing Type_handler_enum::make_table_field() and
   Type_handler_set::make_table_field().

2. Code simplification in Field_str constructor calls.

a. Changing the "CHARSET_INFO *cs" argument in constuctors for Field_str
   and its descendants to "const DTCollation &collation". This is to
   avoid two step initialization:
   - setting Field_str::derivation and Field_str::repertoire to the
     default values first
   - then resetting them using:
     set_derivation(item->derivation, item->repertoire).

b. Removing Field::set_derivation()

c. Adding a new constructor DTCollation(CHARSET_INFO *cs),
   for the old code compatibility.

3. Changes in test results

As a side effect some test results have changed, because
in the old version Item::make_string_field() converted
TINYBLOB to VARCHAR(255). Now TINYBLOB is preserved.

a. sp-row.result
   This query:
     CREATE TABLE t1 AS SELECT tinyblob_sp_variable;
   Now preserves TINYBLOB as the data type.
   Before the patch a VARCHAR(255) was created.

b. gis-debug.result
   This is a debug test, to make sure that + and - operators
   are commutative and non-commutative correspondingly.
   The exact data type is not really important.
   (But anyway, it now chooses a better data type that fits the result)
2017-04-27 14:37:27 +04:00
Alexander Barkov
2fd635409d MDEV-12426 Add Field::type_handler() + MDEV-12432
This is a joint patch for:

- MDEV-12426 Add Field::type_handler()
- MDEV-12432 Range optimizer for ENUM and SET does not return "Impossible WHERE" in some case

With the new type handler approach being added to Field, it was easier to fix
MDEV-12432 rather than to reproduce the old ENUM/SET behavior.

The patch does the following:

1. Adds Field::type_handler(), according to the task description.

2. Fixes the asymmetry between Fields and Items of ENUM and SET field types.
   Field_enum::cmp_type() returned INT_RESULT
   Item*::cmp_type() returned STRING_RESULT for ENUM and SET expressions

This asymmetry was originally done for easier coding in the optimizer sources.
However, in 10.1 we moved a lot of code to methods of the class Field:
- test_if_equality_guarantees_uniqueness()
- can_be_substituted_to_equal_item()
- get_equal_const_item()
- can_optimize_keypart_ref()
- can_optimize_hash_join()
- can_optimize_group_min_max()
- can_optimize_range()
- can_optimize_outer_join_table_elimination()

As of 10.2 only a few lines of the code in opt_range.cc, field.cc and field.h
still relayed on the fact that Field_enum::cmp_type() returns INT_RESULT:
- Some asserts in field.cc
- Field_year::get_copy_func()
- Item_func_like::get_mm_leaf()
- Item_bool_func::get_mm_leaf()
These lines have been fixed.

3. Item_bool_func::get_mm_leaf() did not work well for ENUM/SET,
see MDEV-12432. So the ENUM/SET code was rewritten, and the relevant
code in Field_enum::store() and Field_set::store() was fixed to
properly return errors to the caller.

4. The result of Field_decimal::result_type() was changed from REAL_RESULT
to DECIMAL_RESULT. Data type aggregation (e.g. in COALESCE()) is now more
precise for old DECIMAL, because Item::decimal_precision() now goes through
the DECIMAL_RESULT branch. Earlier it went through the REAL_RESULT branch.
2017-04-25 14:22:07 +04:00
Alexander Barkov
791374354c MDEV-9217 Split Item::tmp_table_field_from_field_type() into virtual methods in Type_handler
- Adding Type_handler::make_table_field() and moving pieces of the code
  from Item::tmp_table_field_from_field_type() to virtual implementations
  for various type handlers.

- Adding a new Type_all_attributes, to access to Item's extended
  attributes, such as decimal_precision() and geometry_type().

- Adding a new class Record_addr, to pass record related information
  to Type_handler methods (ptr, null_ptr and null_bit) as a single structure.
  Note, later it will possibly be extended for BIT-alike field purposes,
  by adding new members (bit_ptr_arg, bit_ofs_arg).

- Moving the code from Field_new_decimal::create_from_item()
  to Type_handler_newdecimal::make_table_field().

- Removing Field_new_decimal() and Field_geom() helper constructor
  variants that were used for temporary field creation.

- Adding Item_field::type_handler(), Field::type_handler() and
  Field_blob::type_handler() to return correct type handlers for
  blob variants, according to Field_blob::packlength.

- Adding Type_handler_blob_common, as a common parent for
  Type_handler_tiny_blob, Type_handler_blob, Type_handler_medium_blob
  and Type_handler_long_blob.

- Implementing Type_handler_blob_common::Item_hybrid_func_fix_attributes().

  It's needed for cases when TEXT variants of different character sets are mixed
  in LEAST, GREATEST, CASE and its abreviations (IF, IFNULL, COALESCE), e.g.:
      CREATE TABLE t1 (
        a TINYTEXT CHARACTER SET latin1,
        b TINYTEXT CHARACTER SET utf8
      );
      CREATE TABLE t2 AS SELECT COALESCE(a,b) FROM t1;
  Type handler aggregation returns TINYTEXT as a common data type
  for the two columns. But as conversion from latin1 to utf8
  happens for "a", the maximum possible length of "a" grows from 255 to 255*3.
  Type_handler_blob_common::Item_hybrid_func_fix_attributes() makes sure
  to update the blob type handler according to max_length.

- Adding Type_handler::blob_type_handler(uint max_octet_length).

- Adding a few m_type_aggregator_for_result.add() pairs, because
  now Item_xxx::type_handler() can return pointers to type_handler_tiny_blob,
  type_handler_blob, type_handler_medium_blob, type_handler_long_blob.
  Before the patch only type_handler_blob was possible result of type_handler().

- Making type_handler_tiny_blob, type_handler_blob, type_handler_medium_blob,
  type_handler_long_blob public.

- Removing the condition in Item_sum_avg::create_tmp_field()
  checking Item_sum_avg::result_type() against DECIMAL_RESULT.
  Now both REAL_RESULT and DECIMAL_RESULT are symmetrically handled
  by tmp_table_field_from_field_type().

- Removing Item_geometry_func::create_field_for_create_select(),
  as the inherited version perfectly works.

- Fixing Item_func_as_wkb::field_type() to return MYSQL_TYPE_LONG_BLOB
  rather than MYSQL_TYPE_BLOB. It's needed to make sure that
  tmp_table_field_from_field_type() creates a LONGBLOB field for AsWKB().

- Fixing Item_func_as_wkt::fix_length_and_dec() to set max_length to
  UINT32_MAX rather than MAX_BLOB_WIDTH, to make sure that
  tmp_table_field_from_field_type() creates a LONGTEXT field for AsWKT().

- Removing Item_func_set_user_var::create_field_for_create_select(),
  as the inherited version works fine.

- Adding Item_func_get_user_var::create_field_for_create_select() to
  make sure that "CREATE TABLE t1 AS SELECT @string_user variable"
  always creates a field of LONGTEXT/LONGBLOB type.

- Item_func_ifnull::create_field_for_create_select()
  behavior has changed. Before the patch it passed set_blob_packflag=false,
  which meant to create LONGBLOB for all blob variants.
  Now it takes into account max_length, which gives better column
  data types for:
    CREATE TABLE t2 AS SELECT IFNULL(blob_column1, blob_column2) FROM t1;

- Fixing Item_func_nullif::fix_length_and_dec() to use
  set_handler(args[2]->type_handler()) instead of
  set_handler_by_field_type(args[2]->field_type()).
  This is needed to distinguish between BLOB variants.

- Implementing Item_blob::type_handler(), to make sure to create
  proper BLOB field variant, according to max_length, for queries like:
    CREATE TABLE t1 AS
      SELECT some_blob_field FROM INFORMATION_SCHEMA.SOME_TABLE;

- Fixing Item_field::real_type_handler() to make sure that
  the code aggregating fields for UNION gets a proper BLOB
  variant type handler from fields.

- Adding a special code into Item_type_holder::make_field_by_type(),
  to make sure that after aggregating field types it also properly
  takes into account max_length when mixing TEXT variants of different
  character sets and chooses a proper TEXT variant:
      CREATE TABLE t1 (
        a TINYTEXT CHARACTER SET latin1,
        b TINYTEXT CHARACTER SET utf8
      );
      CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT b FROM t1;

- Adding tests, for better coverage of IFNULL, NULLIF, UNION.

- The fact that tmp_table_field_from_field_type() now takes
  into account BLOB variants (instead of always creating LONGBLOB),
  tests results for WEIGHT_STRING() and NULLIF() and UNION
  have become more precise.
2017-04-24 12:09:25 +04:00
Monty
5a759d31f7 Changing field::field_name and Item::name to LEX_CSTRING
Benefits of this patch:
- Removed a lot of calls to strlen(), especially for field_string
- Strings generated by parser are now const strings, less chance of
  accidently changing a string
- Removed a lot of calls with LEX_STRING as parameter (changed to pointer)
- More uniform code
- Item::name_length was not kept up to date. Now fixed
- Several bugs found and fixed (Access to null pointers,
  access of freed memory, wrong arguments to printf like functions)
- Removed a lot of casts from (const char*) to (char*)

Changes:
- This caused some ABI changes
  - lex_string_set now uses LEX_CSTRING
  - Some fucntions are now taking const char* instead of char*
- Create_field::change and after changed to LEX_CSTRING
- handler::connect_string, comment and engine_name() changed to LEX_CSTRING
- Checked printf() related calls to find bugs. Found and fixed several
  errors in old code.
- A lot of changes from LEX_STRING to LEX_CSTRING, especially related to
  parsing and events.
- Some changes from LEX_STRING and LEX_STRING & to LEX_CSTRING*
- Some changes for char* to const char*
- Added printf argument checking for my_snprintf()
- Introduced null_clex_str, star_clex_string, temp_lex_str to simplify
  code
- Added item_empty_name and item_used_name to be able to distingush between
  items that was given an empty name and items that was not given a name
  This is used in sql_yacc.yy to know when to give an item a name.
- select table_name."*' is not anymore same as table_name.*
- removed not used function Item::rename()
- Added comparision of item->name_length before some calls to
  my_strcasecmp() to speed up comparison
- Moved Item_sp_variable::make_field() from item.h to item.cc
- Some minimal code changes to avoid copying to const char *
- Fixed wrong error message in wsrep_mysql_parse()
- Fixed wrong code in find_field_in_natural_join() where real_item() was
  set when it shouldn't
- ER_ERROR_ON_RENAME was used with extra arguments.
- Removed some (wrong) ER_OUTOFMEMORY, as alloc_root will already
  give the error.

TODO:
- Check possible unsafe casts in plugin/auth_examples/qa_auth_interface.c
- Change code to not modify LEX_CSTRING for database name
  (as part of lower_case_table_names)
2017-04-23 22:35:46 +03:00
Alexander Barkov
ba670edfa3 MDEV-12559 Split Item::temporal_precision() into virtual methods in Type_handler
- Adding a new virtual method Type_handler::Item_time_precision()
- Adding a new virtual method Type_handler::Item_datetime_precision()
- Removing Item::temporal_precision() and adding Item::time_precision()
  and Item::datetime_precision() instead.
- Moving Item_func_convert_tz::fix_length_and_dec() from item_timefunc.cc
  to item_timefunc.h. It's only two lines, and we're changing it anyway.
- Removing Item_temporal_typecast::fix_length_and_dec_generic(),
  moving this code to
  Type_handler::Item_{date|time|datetime}_typecast_fix_length_and_dec().
  This allows to get rid of one more field_type() call.
  Also, in the old reduction, Item_date_typecast::fix_length_and_dec()
  unnecessarily called args[0]->temporal_precision(). The new reduction
  does not call args[0]->datetime_precision(), as DATE does not
  have fractional digits.
2017-04-22 21:59:00 +04:00
Monty
b478276b04 Removed complex and wrong set_name_for_rollback()
This was wrong because:
- There was no reason to rollback name for item that will be deleted
  after query.
- name_length was not rolled back
- Changing real_item() doesn't work as it may be used many times in the
  same query

After removing all the old code and extending the test case, all the
related test cases passes.

Sanja and I concluded that the old code isn't needed anymore.  If it
still needed for some scenario not covered by our test system, it needs
to be coded in some other way, so better to remove the wrong code.
2017-04-19 22:30:55 +03:00
Jacob Mathew
0b52b28b91 MDEV-10355 Weird error message upon CREATE TABLE with DEFAULT
Fixed handling of default values with cached temporal functions so that the
CREATE TABLE statement now succeeds.
Fixed virtual column session cleanup.
Fixed the error message.
Added quoting of date/time values in cases when this was omitted.
Added a test case in default.test.
Updated test result files.
2017-04-18 17:36:05 -07:00
Jacob Mathew
38af34bb21 MDEV-11117 CHECK constraint fails on intermediate step of ALTER
Fixed the bug by failing the statement with an error message that explains
that an auto-increment column may not be used in an expression for a
check constraint.
Added a test case in check_constraint.test.
Updated existing tests and results.
2017-04-17 15:32:44 -07:00
Alexander Barkov
d433277f53 A cleanup for MDEV-10914 ROW data type for stored routine variables
Addressing Monty's review suggestions
2017-04-05 15:03:02 +04:00
Alexander Barkov
1b8a0c879d MDEV-12133 sql_mode=ORACLE: table%ROWTYPE in variable declarations 2017-04-05 15:02:59 +04:00
Alexander Barkov
72f43df623 MDEV-10914 ROW data type for stored routine variables 2017-04-05 15:02:56 +04:00
Alexander Barkov
46d076d67a MDEV-10577 sql_mode=ORACLE: %TYPE in variable declarations 2017-04-05 15:02:54 +04:00
Alexander Barkov
ec527face3 MDEV-10801 sql_mode: dynamic SQL placeholders 2017-04-05 15:02:49 +04:00
Alexander Barkov
30bec863cf MDEV-10342 Providing compatibility for basic SQL built-in functions
Adding functions NVL() and NVL2().
2017-04-05 15:02:48 +04:00
Alexander Barkov
f00a314f9a Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext 2017-03-31 16:40:29 +04:00
Sergei Golubchik
da4d71d10d Merge branch '10.1' into 10.2 2017-03-30 12:48:42 +02:00
Alexander Barkov
48c59f394b MDEV-12338 Split Item_type_holder::get_real_type() into virtual Item::real_type_handler() 2017-03-24 17:52:55 +04:00
Sergei Golubchik
09a2107b1b Merge branch '10.0' into 10.1 2017-03-21 19:20:44 +01:00
Sergei Golubchik
0d622bed4f Merge branch '5.5' into 10.0 2017-03-21 11:35:50 +01:00
Varun Gupta
adbe1c5fe9 MDEV-6486: Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))'
failed with SELECT SQ, TEXT field

The functon find_all_keys does call Item_subselect::walk, which calls walk() for the subquery
The issue is that when a field is represented by Item_outer_ref(Item_direct_ref(Item_copy_string( ...))).
Item_copy_string does have a pointer to an Item_field in Item_copy::item but does not implement Item::walk method, so we are not
able to set the bitmap for that field. This is the reason why the assert fails.

Fixed by adding the walk method to Item_copy class.
2017-03-14 17:31:29 +05:30
Alexander Barkov
e43156e1a6 Removing the duplicate copy of char_to_byte_length_safe().
It appeared during a merge from 10.2 to bb-10.2-ext.
2017-03-13 17:20:22 +04:00
Alexander Barkov
a4a48a37c4 MDEV-12199 Split Item_func_{abs|neg|int_val}::fix_length_and_dec() into methods in Type_handler 2017-03-10 16:12:58 +04:00
Alexander Barkov
ec8c38a82e Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext 2017-03-08 23:47:20 +04:00
Marko Mäkelä
89d80c1b0b Fix many -Wconversion warnings.
Define my_thread_id as an unsigned type, to avoid mismatch with
ulonglong.  Change some parameters to this type.

Use size_t in a few more places.

Declare many flag constants as unsigned to avoid sign mismatch
when shifting bits or applying the unary ~ operator.

When applying the unary ~ operator to enum constants, explictly
cast the result to an unsigned type, because enum constants can
be treated as signed.

In InnoDB, change the source code line number parameters from
ulint to unsigned type. Also, make some InnoDB functions return
a narrower type (unsigned or uint32_t instead of ulint;
bool instead of ibool).
2017-03-07 19:07:27 +02:00
Alexander Barkov
47b7ffb396 Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext 2017-02-27 10:07:59 +04:00
Sergei Golubchik
6f6d0531dc MDEV-11439 No data type JSON, but CAST(something AS JSON) pretends to work
Use JSON_COMPACT(X) instead of CAST(X AS JSON).
Bonus - X is validated to be a valid JSON.
Fix a typo in the error message.
2017-02-14 20:43:41 +01:00
Sergei Golubchik
cd4dd2b62d MDEV-10201 Bad results for CREATE TABLE t1 (a INT DEFAULT b, b INT DEFAULT 4)
Optionally do table->update_default_fields() even for INSERT
that supposedly provides values for all column. Because these
"values" might be DEFAULT, which would need table->update_default_fields()
at the end.

Also set Item_default_value::used_tables() from the default expression.
Non-zero used_field() means that mysql_insert() will initialize all
fields to their default values (with restore_record()) even if
all columns are later provided with values. Because default expressions
may refer to other columns and they must be initialized.
2017-02-13 18:12:04 +01:00
Sergei Golubchik
ddb284afaa MDEV-11601 Out-of-bounds string access in create_schema_table()
in Item_partition_func_safe_string(THD *thd, const char *name_arg,
uint length, CHARSET_INFO *cs= NULL), the 'name_arg' is the value
of the string constant and 'length' is the length of this constant,
so length == strlen(name_arg).
2017-02-09 16:03:56 +02:00
Alexander Barkov
3f83801d82 MDEV-12001 Split Item_func_round::fix_length_and_dec to virtual methods in Type_handler
This patch makes the following changes (according to the task description):
- Adds Type_handler::Item_func_round_fix_length_and_dec().
- Splits the code from Item_func_round::fix_length_and_dec() into new
  Item_func_round methods fix_arg_int(), fix_arg_decimal(), fix_arg_double().
- Calls the new Item_func_round methods from the relevant implementations of
  Type_handler_xxx::Item_func_round_fix_length_and_dec().
- Adds a new error message ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
- Makes ROUND() return the new error for GEOMETRY

Additionally:
- Inherits Item_func_round directly from Item_func_numhybrid as it
  uses nothing from Item_func_num1.
- Fixes "MDEV-12000 ROUND(expr,const_expr_returning_NULL) creates DOUBLE(0,0)".
  Now if args[1] returns NULL, the data type is set to DOUBLE with
  NOT_FIXED_DEC decimals instead of 0 decimals.
2017-02-07 21:07:28 +04:00
Alexander Barkov
d333e3ad9c Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext 2017-02-02 08:21:42 +04:00
Alexander Barkov
ae91690d89 MDEV-11780 Crash with PREPARE + SP out parameter + literal
Before "MDEV-10709 Expressions as parameters to Dynamic SQL" only
user variables were syntactically allowed as EXECUTE parameters.
User variables were OK as both IN and OUT parameters.
When Item_param was bound to an actual parameter (a user variable),
it automatically meant that the bound Item was settable.
The DBUG_ASSERT() in Protocol_text::send_out_parameters() guarded that
the actual parameter is really settable.

After MDEV-10709, any kind of expressions are allowed as EXECUTE IN parameters.
But the patch for MDEV-10709 forgot to check that only descendants of
Settable_routine_parameter should be allowed as OUT parameters.
So an attempt to pass a non-settable parameter as an OUT parameter
made server crash on the above mentioned DBUG_ASSERT.

This patch changes Item_param::get_settable_routine_parameter(),
which previously always returned "this". Now, when Item_param is bound
to some Item, it caches if the bound Item is settable.
Item_param::get_settable_routine_parameter() now returns "this" only
if the bound actual parameter is settable, and returns NULL otherwise.
2017-01-24 17:22:06 +04:00