← Back to team overview

maria-developers team mailing list archive

Review request MDEV-6274 Collation usage statistics (for feedback plugin)

 

Hello Sergei,

Please review a patch for MDEV-6274.

Thanks.
=== modified file 'include/my_sys.h'
--- include/my_sys.h	2014-04-15 07:29:57 +0000
+++ include/my_sys.h	2014-05-28 14:01:40 +0000
@@ -242,6 +242,11 @@ extern MYSQL_PLUGIN_IMPORT CHARSET_INFO
 extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *all_charsets[MY_ALL_CHARSETS_SIZE];
 extern struct charset_info_st compiled_charsets[];
 
+/* Collation properties and use statistics */
+extern my_bool my_collation_is_known_id(uint id);
+extern ulonglong my_collation_statistics_get_use_count(uint id);
+extern const char *my_collation_get_tailoring(uint id);
+
 /* statistics */
 extern ulong	my_file_opened,my_stream_opened, my_tmp_file_created;
 extern ulong    my_file_total_opened;

=== modified file 'mysql-test/r/ctype_ldml.result'
--- mysql-test/r/ctype_ldml.result	2013-11-12 12:48:57 +0000
+++ mysql-test/r/ctype_ldml.result	2014-05-28 13:45:54 +0000
@@ -9,6 +9,9 @@ character_sets_dir	MYSQL_TEST_DIR/std_da
 show collation like 'utf8_phone_ci';
 Collation	Charset	Id	Default	Compiled	Sortlen
 utf8_phone_ci	utf8	352			8
+SELECT COLLATIONPROPERTY('utf8_phone_ci', 'Tailoring');
+COLLATIONPROPERTY('utf8_phone_ci', 'Tailoring')
+ &\u0000=\u0020=\u0028=\u0029=\u002B=\u002D
 CREATE TABLE t1 (
 name VARCHAR(64),
 phone VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_phone_ci
@@ -56,6 +59,9 @@ drop table t1;
 show collation like 'utf8mb4_test_ci';
 Collation	Charset	Id	Default	Compiled	Sortlen
 utf8mb4_test_ci	utf8mb4	326			8
+SELECT COLLATIONPROPERTY('utf8mb4_test_ci', 'Tailoring');
+COLLATIONPROPERTY('utf8mb4_test_ci', 'Tailoring')
+[version 5.2.0] &a<<b=\u10062 &\u10400=\u100400 &d<d\u017e<<<D\u017e<<<D\u017d
 create table t1 (c1 char(1) character set utf8mb4 collate utf8mb4_test_ci);
 insert into t1 values ('a');
 select * from t1 where c1='b';
@@ -65,6 +71,9 @@ drop table t1;
 show collation like 'utf16_test_ci';
 Collation	Charset	Id	Default	Compiled	Sortlen
 utf16_test_ci	utf16	327			8
+SELECT COLLATIONPROPERTY('utf16_test_ci', 'Tailoring');
+COLLATIONPROPERTY('utf16_test_ci', 'Tailoring')
+ &a<<b
 create table t1 (c1 char(1) character set utf16 collate utf16_test_ci);
 insert into t1 values ('a');
 select * from t1 where c1='b';
@@ -74,6 +83,9 @@ drop table t1;
 show collation like 'utf32_test_ci';
 Collation	Charset	Id	Default	Compiled	Sortlen
 utf32_test_ci	utf32	391			8
+SELECT COLLATIONPROPERTY('utf32_test_ci', 'Tailoring');
+COLLATIONPROPERTY('utf32_test_ci', 'Tailoring')
+ &a<<b
 create table t1 (c1 char(1) character set utf32 collate utf32_test_ci);
 insert into t1 values ('a');
 select * from t1 where c1='b';
@@ -507,6 +519,9 @@ SHOW COLLATION LIKE 'utf8_phone_ci';
 Collation	Charset	Id	Default	Compiled	Sortlen
 utf8_phone_ci	utf8	352			8
 SET NAMES utf8;
+SELECT COLLATIONPROPERTY('utf8mb4_test_400_ci', 'Tailoring');
+COLLATIONPROPERTY('utf8mb4_test_400_ci', 'Tailoring')
+[version 4.0.0]
 SELECT hex(weight_string(_utf8mb4'a' collate utf8mb4_test_400_ci));
 hex(weight_string(_utf8mb4'a' collate utf8mb4_test_400_ci))
 0E33
@@ -832,6 +847,9 @@ Warning	1273	Syntax error at '[strength
 #
 # WL#5624, reset before primary ignorable
 #
+SELECT COLLATIONPROPERTY('utf8_5624_3', 'Tailoring');
+COLLATIONPROPERTY('utf8_5624_3', 'Tailoring')
+ &[before primary][first secondary ignorable]<lb-fsi
 SET NAMES utf8 COLLATE utf8_5624_3;
 ERROR HY000: Unknown collation: 'utf8_5624_3'
 SHOW WARNINGS;
@@ -841,6 +859,9 @@ Warning	1273	Can't reset before a primar
 #
 # WL#5624, \u without hex digits is equal to {'\', 'u'}
 #
+SELECT COLLATIONPROPERTY('utf8_5624_4', 'Tailoring');
+COLLATIONPROPERTY('utf8_5624_4', 'Tailoring')
+ &\u=x
 SET NAMES utf8 COLLATE utf8_5624_4;
 CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
 INSERT INTO t1 VALUES ('\\'),('u'),('x'),('X');
@@ -1065,6 +1086,9 @@ DROP TABLE t1;
 #
 # WL#5624, shift after, using expansion
 #
+SELECT COLLATIONPROPERTY('utf8_5624_5', 'Tailoring');
+COLLATIONPROPERTY('utf8_5624_5', 'Tailoring')
+[shift-after-method expand] &0<<001<<002<a<b<c<d<e<f<g<h<i<j<k<l<m<n<o<p<q<r<s<t<u<v<w<x<y<z<aa<aaa &[before primary]1<A<B<C<D<E<F<G<H<I<J<K<L<M<N<O<P<Q<R<S<T<U<V<W<X<Y<Z<AA<AAA
 SET NAMES utf8 COLLATE utf8_5624_5;
 CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
 INSERT INTO t1 VALUES ('0'),('1'),('0z'),(_ucs2 0x0030FF9D);
@@ -1142,6 +1166,9 @@ AA	0E293358
 AAA	0E293359
 1	0E2A
 DROP TABLE t1;
+SELECT COLLATIONPROPERTY('utf8_5624_5_bad', 'Tailoring');
+COLLATIONPROPERTY('utf8_5624_5_bad', 'Tailoring')
+[shift-after-method expand] &a-a4<xxx04 &a-aa5<xxx05 &a-aaa6<xxx06 &a-aaaa7<xxx07 &a-aaaaa8<xxx08 &a-aaaaaa9<xxx09 &a-aaaaaa10<xxx10
 SET NAMES utf8 COLLATE utf8_5624_5_bad;
 ERROR HY000: Unknown collation: 'utf8_5624_5_bad'
 SHOW WARNINGS;

=== modified file 'mysql-test/r/ctype_uca.result'
--- mysql-test/r/ctype_uca.result	2014-05-09 10:35:11 +0000
+++ mysql-test/r/ctype_uca.result	2014-05-29 05:05:09 +0000
@@ -12856,5 +12856,179 @@ DROP TABLE t1;
 # END of ctype_myanmar.inc
 #
 #
+# MDEV-6274 Collation usage statistics
+#
+SET NAMES utf8;
+SELECT COLLATIONPROPERTY(192,'UseCount')>0;
+COLLATIONPROPERTY(192,'UseCount')>0
+1
+SELECT COLLATIONPROPERTY('utf8_spanish_ci','tailoring');
+COLLATIONPROPERTY('utf8_spanish_ci','tailoring')
+& N < \u00F1 <<< \u00D1 
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','tailoring');
+COLLATIONPROPERTY('utf8_unicode_ci','tailoring')
+
+SELECT COLLATIONPROPERTY('utf8_general_ci','tailoring');
+COLLATIONPROPERTY('utf8_general_ci','tailoring')
+NULL
+SELECT COLLATIONPROPERTY('latin1_general_ci','tailoring');
+COLLATIONPROPERTY('latin1_general_ci','tailoring')
+NULL
+SELECT COLLATIONPROPERTY(192.0,'UseCount')>0;
+COLLATIONPROPERTY(192.0,'UseCount')>0
+1
+SELECT COLLATIONPROPERTY(192e0,'UseCount')>0;
+COLLATIONPROPERTY(192e0,'UseCount')>0
+1
+SELECT COLLATIONPROPERTY(DATE'0192-01-01','UseCount')>0;
+COLLATIONPROPERTY(DATE'0192-01-01','UseCount')>0
+NULL
+Warnings:
+Warning	1273	Unknown collation: '0192-01-01'
+SELECT COLLATIONPROPERTY(9999.0,'UseCount')>0;
+COLLATIONPROPERTY(9999.0,'UseCount')>0
+NULL
+Warnings:
+Warning	1273	Unknown collation: '#9999'
+SELECT COLLATIONPROPERTY(9999e0,'UseCount')>0;
+COLLATIONPROPERTY(9999e0,'UseCount')>0
+NULL
+Warnings:
+Warning	1273	Unknown collation: '#9999'
+SELECT COLLATIONPROPERTY(DATE'9999-01-01','UseCount')>0;
+COLLATIONPROPERTY(DATE'9999-01-01','UseCount')>0
+NULL
+Warnings:
+Warning	1273	Unknown collation: '9999-01-01'
+CREATE TABLE t1 AS SELECT COLLATIONPROPERTY(192,'UseCount');
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `COLLATIONPROPERTY(192,'UseCount')` longtext CHARACTER SET utf8
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SELECT COLLATIONPROPERTY('unknown-collation-name','unknown-property');
+COLLATIONPROPERTY('unknown-collation-name','unknown-property')
+NULL
+Warnings:
+Warning	1273	Unknown collation: 'unknown-collation-name'
+Warning	1210	Incorrect arguments to COLLATIONPROPERTY
+SELECT COLLATIONPROPERTY(_latin1 0x6162FF,'unknown-property');
+COLLATIONPROPERTY(_latin1 0x6162FF,'unknown-property')
+NULL
+Warnings:
+Warning	1273	Unknown collation: 'abÿ'
+Warning	1210	Incorrect arguments to COLLATIONPROPERTY
+SELECT COLLATIONPROPERTY('utf8_general_ci','unknown-property');
+COLLATIONPROPERTY('utf8_general_ci','unknown-property')
+NULL
+Warnings:
+Warning	1210	Incorrect arguments to COLLATIONPROPERTY
+SELECT COLLATIONPROPERTY(0,'UseCount');
+COLLATIONPROPERTY(0,'UseCount')
+NULL
+Warnings:
+Warning	1273	Unknown collation: '#0'
+SELECT COLLATIONPROPERTY(3000,'UseCount');
+COLLATIONPROPERTY(3000,'UseCount')
+NULL
+Warnings:
+Warning	1273	Unknown collation: '#3000'
+SELECT COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0;
+COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0
+1
+SELECT COLLATIONPROPERTY('utf8_general_ci','UseCount')>0;
+COLLATIONPROPERTY('utf8_general_ci','UseCount')>0
+1
+SELECT COLLATIONPROPERTY('utf8_general_ci','usecount')>0;
+COLLATIONPROPERTY('utf8_general_ci','usecount')>0
+1
+SELECT COLLATIONPROPERTY('UTF8_General_CI','usecount')>0;
+COLLATIONPROPERTY('UTF8_General_CI','usecount')>0
+1
+SET NAMES utf8 COLLATE utf8_bin;
+SELECT COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0;
+COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0
+1
+SELECT COLLATIONPROPERTY('utf8_general_ci','UseCount')>0;
+COLLATIONPROPERTY('utf8_general_ci','UseCount')>0
+1
+SELECT COLLATIONPROPERTY('utf8_general_ci','usecount')>0;
+COLLATIONPROPERTY('utf8_general_ci','usecount')>0
+1
+SELECT COLLATIONPROPERTY('UTF8_General_CI','usecount')>0;
+COLLATIONPROPERTY('UTF8_General_CI','usecount')>0
+1
+SET collation_connection=ucs2_general_ci;
+SELECT COLLATIONPROPERTY('unknown-collation-name','unknown-property');
+COLLATIONPROPERTY('unknown-collation-name','unknown-property')
+NULL
+Warnings:
+Warning	1273	Unknown collation: 'unknown-collation-name'
+Warning	1210	Incorrect arguments to COLLATIONPROPERTY
+SELECT COLLATIONPROPERTY('utf8_general_ci','unknown-property');
+COLLATIONPROPERTY('utf8_general_ci','unknown-property')
+NULL
+Warnings:
+Warning	1210	Incorrect arguments to COLLATIONPROPERTY
+SELECT COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0;
+COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0
+1
+SELECT COLLATIONPROPERTY('utf8_general_ci','UseCount')>0;
+COLLATIONPROPERTY('utf8_general_ci','UseCount')>0
+1
+SELECT COLLATIONPROPERTY('utf8_general_ci','usecount')>0;
+COLLATIONPROPERTY('utf8_general_ci','usecount')>0
+1
+SELECT COLLATIONPROPERTY('UTF8_General_CI','usecount')>0;
+COLLATIONPROPERTY('UTF8_General_CI','usecount')>0
+1
+SET NAMES utf8;
+SELECT COLLATION_NAME, COLLATIONPROPERTY(COLLATION_NAME,'tailoring')
+FROM INFORMATION_SCHEMA.COLLATIONS
+WHERE COLLATION_NAME LIKE 'utf8_spanish%'
+ORDER BY COLLATION_NAME;
+COLLATION_NAME	COLLATIONPROPERTY(COLLATION_NAME,'tailoring')
+utf8_spanish2_ci	&C <  ch <<< Ch <<< CH&L <  ll <<< Ll <<< LL&N < \u00F1 <<< \u00D1
+utf8_spanish_ci	& N < \u00F1 <<< \u00D1 
+CREATE TABLE t1 (property VARCHAR(20));
+INSERT INTO t1 VALUES ('Tailoring'),('Unknown');
+SELECT property, COLLATIONPROPERTY('utf8_spanish_ci',property)
+FROM t1 ORDER BY property;
+property	COLLATIONPROPERTY('utf8_spanish_ci',property)
+Tailoring	& N < \u00F1 <<< \u00D1 
+Unknown	NULL
+Warnings:
+Warning	1210	Incorrect arguments to COLLATIONPROPERTY
+DROP TABLE t1;
+SET @count=COLLATIONPROPERTY('utf8_unicode_ci','UseCount');
+SELECT _utf8'test' COLLATE utf8_unicode_ci;
+_utf8'test' COLLATE utf8_unicode_ci
+test
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count
+1
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci);
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count
+3
+SELECT * FROM t1;
+a
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count
+4
+SELECT * FROM t1;
+a
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count
+4
+FLUSH TABLES;
+SELECT * FROM t1;
+a
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count
+5
+DROP TABLE t1;
+#
 # End of MariaDB-10.0 tests
 #

=== modified file 'mysql-test/suite/plugins/r/feedback_plugin_load.result'
--- mysql-test/suite/plugins/r/feedback_plugin_load.result	2012-04-18 02:00:08 +0000
+++ mysql-test/suite/plugins/r/feedback_plugin_load.result	2014-05-28 12:57:54 +0000
@@ -10,3 +10,12 @@ FEEDBACK_SEND_RETRY_WAIT	60
 FEEDBACK_SEND_TIMEOUT	60
 FEEDBACK_URL	http://mariadb.org/feedback_plugin/post
 FEEDBACK_USER_INFO	mysql-test
+SELECT VARIABLE_VALUE>0, VARIABLE_NAME FROM INFORMATION_SCHEMA.FEEDBACK
+WHERE VARIABLE_NAME LIKE 'Collation_usecount%'
+ORDER BY VARIABLE_NAME;
+VARIABLE_VALUE>0	VARIABLE_NAME
+1	Collation_usecount binary
+1	Collation_usecount latin1_bin
+1	Collation_usecount latin1_swedish_ci
+1	Collation_usecount utf8_bin
+1	Collation_usecount utf8_general_ci

=== modified file 'mysql-test/suite/plugins/t/feedback_plugin_load.test'
--- mysql-test/suite/plugins/t/feedback_plugin_load.test	2011-12-02 15:26:43 +0000
+++ mysql-test/suite/plugins/t/feedback_plugin_load.test	2014-05-28 12:57:27 +0000
@@ -8,3 +8,7 @@ select plugin_status from information_sc
 --sorted_result
 select * from information_schema.feedback where variable_name like 'feed%'
        and variable_name not like  '%_uid';
+
+SELECT VARIABLE_VALUE>0, VARIABLE_NAME FROM INFORMATION_SCHEMA.FEEDBACK
+WHERE VARIABLE_NAME LIKE 'Collation_usecount%'
+ORDER BY VARIABLE_NAME;

=== modified file 'mysql-test/t/ctype_ldml.test'
--- mysql-test/t/ctype_ldml.test	2013-11-12 12:48:57 +0000
+++ mysql-test/t/ctype_ldml.test	2014-05-28 13:45:38 +0000
@@ -16,6 +16,7 @@ set names utf8;
 show variables like 'character_sets_dir%';
 
 show collation like 'utf8_phone_ci';
+SELECT COLLATIONPROPERTY('utf8_phone_ci', 'Tailoring');
 CREATE TABLE t1 (
  name VARCHAR(64),
  phone VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_phone_ci
@@ -44,18 +45,21 @@ select * from t1 where c1='b';
 drop table t1;
 
 show collation like 'utf8mb4_test_ci';
+SELECT COLLATIONPROPERTY('utf8mb4_test_ci', 'Tailoring');
 create table t1 (c1 char(1) character set utf8mb4 collate utf8mb4_test_ci);
 insert into t1 values ('a');
 select * from t1 where c1='b';
 drop table t1;
 
 show collation like 'utf16_test_ci';
+SELECT COLLATIONPROPERTY('utf16_test_ci', 'Tailoring');
 create table t1 (c1 char(1) character set utf16 collate utf16_test_ci);
 insert into t1 values ('a');
 select * from t1 where c1='b';
 drop table t1;
 
 show collation like 'utf32_test_ci';
+SELECT COLLATIONPROPERTY('utf32_test_ci', 'Tailoring');
 create table t1 (c1 char(1) character set utf32 collate utf32_test_ci);
 insert into t1 values ('a');
 select * from t1 where c1='b';
@@ -204,6 +208,7 @@ SHOW COLLATION LIKE 'utf8_phone_ci';
 SET NAMES utf8;
 
 # make sure utf8mb4_test_400_ci is Unicode-4.0.0 based
+SELECT COLLATIONPROPERTY('utf8mb4_test_400_ci', 'Tailoring');
 SELECT hex(weight_string(_utf8mb4'a' collate utf8mb4_test_400_ci));
 SELECT hex(weight_string(convert(_utf32 0x10002 using utf8mb4) collate utf8mb4_test_400_ci));
 SELECT hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
@@ -280,6 +285,7 @@ SHOW WARNINGS;
 --echo #
 --echo # WL#5624, reset before primary ignorable
 --echo #
+SELECT COLLATIONPROPERTY('utf8_5624_3', 'Tailoring');
 --error ER_UNKNOWN_COLLATION
 SET NAMES utf8 COLLATE utf8_5624_3;
 SHOW WARNINGS;
@@ -287,6 +293,7 @@ SHOW WARNINGS;
 --echo #
 --echo # WL#5624, \u without hex digits is equal to {'\\', 'u'}
 --echo #
+SELECT COLLATIONPROPERTY('utf8_5624_4', 'Tailoring');
 SET NAMES utf8 COLLATE utf8_5624_4;
 CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
 INSERT INTO t1 VALUES ('\\'),('u'),('x'),('X');
@@ -353,6 +360,7 @@ DROP TABLE t1;
 --echo #
 --echo # WL#5624, shift after, using expansion
 --echo #
+SELECT COLLATIONPROPERTY('utf8_5624_5', 'Tailoring');
 SET NAMES utf8 COLLATE utf8_5624_5;
 CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
 INSERT INTO t1 VALUES ('0'),('1'),('0z'),(_ucs2 0x0030FF9D);
@@ -369,6 +377,7 @@ INSERT INTO t1 VALUES ('001'),('002');
 SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
 DROP TABLE t1;
 
+SELECT COLLATIONPROPERTY('utf8_5624_5_bad', 'Tailoring');
 --error ER_UNKNOWN_COLLATION
 SET NAMES utf8 COLLATE utf8_5624_5_bad;
 SHOW WARNINGS;

=== modified file 'mysql-test/t/ctype_uca.test'
--- mysql-test/t/ctype_uca.test	2013-12-20 08:42:33 +0000
+++ mysql-test/t/ctype_uca.test	2014-05-29 05:04:33 +0000
@@ -579,6 +579,116 @@ SET NAMES utf8 COLLATE utf8_myanmar_ci;
 SET collation_connection=ucs2_myanmar_ci;
 --source include/ctype_myanmar.inc
 
+
+--echo #
+--echo # MDEV-6274 Collation usage statistics
+--echo #
+SET NAMES utf8;
+SELECT COLLATIONPROPERTY(192,'UseCount')>0;
+SELECT COLLATIONPROPERTY('utf8_spanish_ci','tailoring');
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','tailoring');
+SELECT COLLATIONPROPERTY('utf8_general_ci','tailoring');
+SELECT COLLATIONPROPERTY('latin1_general_ci','tailoring');
+
+#
+# Checking unexpected data types
+#
+SELECT COLLATIONPROPERTY(192.0,'UseCount')>0;
+SELECT COLLATIONPROPERTY(192e0,'UseCount')>0;
+SELECT COLLATIONPROPERTY(DATE'0192-01-01','UseCount')>0;
+SELECT COLLATIONPROPERTY(9999.0,'UseCount')>0;
+SELECT COLLATIONPROPERTY(9999e0,'UseCount')>0;
+SELECT COLLATIONPROPERTY(DATE'9999-01-01','UseCount')>0;
+
+#
+# Checking return data type
+#
+CREATE TABLE t1 AS SELECT COLLATIONPROPERTY(192,'UseCount');
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+#
+# Checking bad collation names and bad property names
+#
+SELECT COLLATIONPROPERTY('unknown-collation-name','unknown-property');
+SELECT COLLATIONPROPERTY(_latin1 0x6162FF,'unknown-property');
+SELECT COLLATIONPROPERTY('utf8_general_ci','unknown-property');
+
+#
+# Checking bad collation IDs
+#
+SELECT COLLATIONPROPERTY(0,'UseCount');
+SELECT COLLATIONPROPERTY(3000,'UseCount');
+
+#
+# Checking that collation names and property names are case insensitive
+#
+SELECT COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0;
+SELECT COLLATIONPROPERTY('utf8_general_ci','UseCount')>0;
+SELECT COLLATIONPROPERTY('utf8_general_ci','usecount')>0;
+SELECT COLLATIONPROPERTY('UTF8_General_CI','usecount')>0;
+
+#
+# Checking that collation names and property names are case insensitive
+# even with a case sensitive session collation.
+#
+SET NAMES utf8 COLLATE utf8_bin;
+SELECT COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0;
+SELECT COLLATIONPROPERTY('utf8_general_ci','UseCount')>0;
+SELECT COLLATIONPROPERTY('utf8_general_ci','usecount')>0;
+SELECT COLLATIONPROPERTY('UTF8_General_CI','usecount')>0;
+
+#
+# Checking that it works fine with tricky session character sets
+#
+SET collation_connection=ucs2_general_ci;
+SELECT COLLATIONPROPERTY('unknown-collation-name','unknown-property');
+SELECT COLLATIONPROPERTY('utf8_general_ci','unknown-property');
+SELECT COLLATIONPROPERTY('utf8_general_ci','USECOUNT')>0;
+SELECT COLLATIONPROPERTY('utf8_general_ci','UseCount')>0;
+SELECT COLLATIONPROPERTY('utf8_general_ci','usecount')>0;
+SELECT COLLATIONPROPERTY('UTF8_General_CI','usecount')>0;
+SET NAMES utf8;
+
+#
+# Checking non-constant collation names
+#
+SELECT COLLATION_NAME, COLLATIONPROPERTY(COLLATION_NAME,'tailoring')
+FROM INFORMATION_SCHEMA.COLLATIONS
+WHERE COLLATION_NAME LIKE 'utf8_spanish%'
+ORDER BY COLLATION_NAME;
+
+#
+# Checking non-constant property names
+#
+CREATE TABLE t1 (property VARCHAR(20));
+INSERT INTO t1 VALUES ('Tailoring'),('Unknown');
+SELECT property, COLLATIONPROPERTY('utf8_spanish_ci',property)
+FROM t1 ORDER BY property;
+DROP TABLE t1;
+
+#
+# Checking how UseCount increments.
+# - Explicit COLLATE clause in an expression increments.
+# - Explicit or implicit collation in CREATE TABLE increments.
+# - The first SELECT forces open_table_def() and increments.
+# - All consequent SELECTs from the same table DO NOT increment.
+# - A SELECT after a "FLUSH TABLES" forces open_table_def(), thus increments.
+#
+SET @count=COLLATIONPROPERTY('utf8_unicode_ci','UseCount');
+SELECT _utf8'test' COLLATE utf8_unicode_ci;
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci);
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+SELECT * FROM t1;
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+SELECT * FROM t1;
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+FLUSH TABLES;
+SELECT * FROM t1;
+SELECT COLLATIONPROPERTY('utf8_unicode_ci','UseCount') - @count;
+DROP TABLE t1;
+
 --echo #
 --echo # End of MariaDB-10.0 tests
 --echo #

=== modified file 'mysys/charset.c'
--- mysys/charset.c	2013-11-08 22:20:07 +0000
+++ mysys/charset.c	2014-05-29 05:20:11 +0000
@@ -483,6 +483,50 @@ void add_compiled_collation(struct chars
 static my_pthread_once_t charsets_initialized= MY_PTHREAD_ONCE_INIT;
 static my_pthread_once_t charsets_template= MY_PTHREAD_ONCE_INIT;
 
+typedef struct
+{
+  ulonglong use_count;
+} MY_COLLATION_STATISTICS;
+
+
+static MY_COLLATION_STATISTICS my_collation_statistics[MY_ALL_CHARSETS_SIZE];
+
+
+my_bool my_collation_is_known_id(uint id)
+{
+  return id > 0 && id < array_elements(all_charsets) && all_charsets[id] ?
+         TRUE : FALSE;
+}
+
+
+/*
+  Collation use statistics functions do not lock
+  counters to avoid mutex contention. This can lose
+  some counter increments with high thread concurrency.
+  But this should be Ok, as we don't need exact numbers.
+*/
+static inline void my_collation_statistics_inc_use_count(uint id)
+{
+  DBUG_ASSERT(my_collation_is_known_id(id));
+  my_collation_statistics[id].use_count++;
+}
+
+
+ulonglong my_collation_statistics_get_use_count(uint id)
+{
+  DBUG_ASSERT(my_collation_is_known_id(id));
+  return my_collation_statistics[id].use_count;
+}
+
+
+const char *my_collation_get_tailoring(uint id)
+{
+  /* all_charsets[id]->tailoring is never changed after server startup. */
+  DBUG_ASSERT(my_collation_is_known_id(id));
+  return all_charsets[id]->tailoring;
+}
+
+
 static void init_available_charsets(void)
 {
   char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
@@ -490,6 +534,7 @@ static void init_available_charsets(void
   MY_CHARSET_LOADER loader;
 
   bzero((char*) &all_charsets,sizeof(all_charsets));
+  bzero((char*) &my_collation_statistics, sizeof(my_collation_statistics));
   init_compiled_charsets(MYF(0));
 
   /* Copy compiled charsets */
@@ -608,7 +653,10 @@ get_internal_charset(MY_CHARSET_LOADER *
   if ((cs= (struct charset_info_st*) all_charsets[cs_number]))
   {
     if (cs->state & MY_CS_READY)  /* if CS is already initialized */
-        return cs;
+    {
+      my_collation_statistics_inc_use_count(cs_number);
+      return cs;
+    }
 
     /*
       To make things thread safe we are not allowing other threads to interfere
@@ -636,6 +684,7 @@ get_internal_charset(MY_CHARSET_LOADER *
         else
           cs->state|= MY_CS_READY;
       }
+      my_collation_statistics_inc_use_count(cs_number);
     }
     else
       cs= NULL;

=== modified file 'plugin/feedback/feedback.cc'
--- plugin/feedback/feedback.cc	2014-03-19 08:56:46 +0000
+++ plugin/feedback/feedback.cc	2014-05-28 10:33:58 +0000
@@ -217,7 +217,8 @@ int fill_feedback(THD *thd, TABLE_LIST *
   tables->schema_table= i_s_feedback;
   res= res || fill_plugin_version(thd, tables)
            || fill_misc_data(thd, tables)
-           || fill_linux_info(thd, tables);
+           || fill_linux_info(thd, tables)
+           || fill_collation_statistics(thd, tables);
 
   return res;
 }

=== modified file 'plugin/feedback/feedback.h'
--- plugin/feedback/feedback.h	2012-01-13 14:50:02 +0000
+++ plugin/feedback/feedback.h	2014-05-28 10:33:49 +0000
@@ -22,6 +22,7 @@ int fill_feedback(THD *thd, TABLE_LIST *
 int fill_plugin_version(THD *thd, TABLE_LIST *tables);
 int fill_misc_data(THD *thd, TABLE_LIST *tables);
 int fill_linux_info(THD *thd, TABLE_LIST *tables);
+int fill_collation_statistics(THD *thd, TABLE_LIST *tables);
 
 static const int SERVER_UID_SIZE= 29;
 extern char server_uid_buf[SERVER_UID_SIZE+1], *user_info;

=== modified file 'plugin/feedback/utils.cc'
--- plugin/feedback/utils.cc	2013-11-20 11:05:39 +0000
+++ plugin/feedback/utils.cc	2014-05-28 10:34:11 +0000
@@ -383,6 +383,25 @@ int fill_misc_data(THD *thd, TABLE_LIST
   return 0;
 }
 
+int fill_collation_statistics(THD *thd, TABLE_LIST *tables)
+{
+  TABLE *table= tables->table;
+  for (uint id= 1; id < MY_ALL_CHARSETS_SIZE; id++)
+  {
+    ulonglong count;
+    if (my_collation_is_known_id(id) &&
+        (count= my_collation_statistics_get_use_count(id)))
+    {
+      char name[MY_CS_NAME_SIZE + 32];
+      size_t namelen= my_snprintf(name, sizeof(name),
+                                 "Collation_usecount %s",
+                                 get_charset_name(id));
+      INSERT2(name, namelen, (count, UNSIGNED));
+    }
+  }
+  return 0;
+};
+
 /**
   calculates the server unique identifier
   

=== modified file 'sql/item_create.cc'
--- sql/item_create.cc	2014-02-27 07:21:41 +0000
+++ sql/item_create.cc	2014-05-29 04:04:14 +0000
@@ -628,6 +628,24 @@ class Create_func_decode_histogram : pub
 };
 
 
+class Create_func_collationproperty : public Create_func_arg2
+{
+public:
+  Item *create_2_arg(THD *thd, Item *arg1, Item *arg2)
+  {
+    return new (thd->mem_root) Item_func_collationproperty(arg1, arg2);
+  }
+
+  static Create_func_collationproperty s_singleton;
+
+protected:
+  Create_func_collationproperty() {}
+  virtual ~Create_func_collationproperty() {}
+};
+
+Create_func_collationproperty Create_func_collationproperty::s_singleton;
+
+
 class Create_func_concat_ws : public Create_native_func
 {
 public:
@@ -5523,6 +5541,7 @@ static Native_func_registry func_array[]
   { { C_STRING_WITH_LEN("CHARACTER_LENGTH") }, BUILDER(Create_func_char_length)},
   { { C_STRING_WITH_LEN("CHAR_LENGTH") }, BUILDER(Create_func_char_length)},
   { { C_STRING_WITH_LEN("COERCIBILITY") }, BUILDER(Create_func_coercibility)},
+  { { C_STRING_WITH_LEN("COLLATIONPROPERTY") }, BUILDER(Create_func_collationproperty)},
   { { C_STRING_WITH_LEN("COLUMN_CHECK") }, BUILDER(Create_func_dyncol_check)},
   { { C_STRING_WITH_LEN("COLUMN_EXISTS") }, BUILDER(Create_func_dyncol_exists)},
   { { C_STRING_WITH_LEN("COLUMN_LIST") }, BUILDER(Create_func_dyncol_list)},

=== modified file 'sql/item_strfunc.cc'
--- sql/item_strfunc.cc	2014-05-09 10:35:11 +0000
+++ sql/item_strfunc.cc	2014-05-29 05:07:24 +0000
@@ -3473,6 +3473,116 @@ String *Item_func_collation::val_str(Str
 }
 
 
+Item_func_collationproperty::Property
+Item_func_collationproperty::get_property(Item *item)
+{
+  StringBuffer<64> tmp;
+  String *property= item->val_str_ascii(&tmp);
+  if (!property)
+    return UNKNOWN_PROPERTY;
+  if (streq(property, STRING_WITH_LEN("USECOUNT")))
+    return USECOUNT;
+  if (streq(property, STRING_WITH_LEN("TAILORING")))
+    return TAILORING;
+  push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
+                      ER_WRONG_ARGUMENTS, ER(ER_WRONG_ARGUMENTS),
+                      "COLLATIONPROPERTY");
+  return UNKNOWN_PROPERTY;
+}
+
+
+void Item_func_collationproperty::unknown_collation_warning(const char *arg)
+{
+  push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
+                      ER_UNKNOWN_COLLATION, ER(ER_UNKNOWN_COLLATION), arg);
+}
+
+
+uint Item_func_collationproperty::get_id(Item *item)
+{
+  longlong id;
+  switch (item->result_type())
+  {
+  case STRING_RESULT:
+    {
+      StringBuffer<MY_CS_NAME_SIZE> buf;
+      String *tmp= item->val_str_ascii(&buf);
+      const char *ptr;
+      if (!tmp || !(ptr= tmp->c_ptr()))
+        return 0;
+      if (!(id= get_collation_number(ptr)))
+      {
+        ErrConvString err(tmp);
+        unknown_collation_warning(err.ptr());
+      }
+    }
+    break;
+  case INT_RESULT:
+  case REAL_RESULT:
+  case DECIMAL_RESULT:
+    id= item->val_int();
+    if (item->null_value)
+      return 0;
+    if (!my_collation_is_known_id(id))
+    {
+      char buff[STRING_BUFFER_USUAL_SIZE + 1]= "#";
+      llstr(id, buff + 1);
+      unknown_collation_warning(buff);
+      id= 0;
+    }
+    break;
+  case TIME_RESULT:
+  case ROW_RESULT:
+  case IMPOSSIBLE_RESULT:
+    DBUG_ASSERT(0);
+    id= 0;
+  }
+  return (uint) id;
+}
+
+
+String *Item_func_collationproperty::val_str(String *str)
+{
+  DBUG_ASSERT(fixed == 1);
+  longlong id= args[0]->basic_const_item()? cached_id : get_id(args[0]);
+  Property property= args[1]->basic_const_item() ?
+                     cached_property : get_property(args[1]);
+  if ((null_value= (id == 0)))
+    return NULL;
+  DBUG_ASSERT(my_collation_is_known_id(id));
+  switch (property)
+  {
+  case USECOUNT:
+    {
+      str->set_int(my_collation_statistics_get_use_count(id),
+                   true, collation.collation);
+      return str;
+    }
+  case TAILORING:
+    {
+      /*
+        my_collation_get_tailoring() returns
+        all_charsets[xxx]->tailoring, which is is initialized
+        during server startup and is never changed afterwards.
+        If we ever want to modify tailorings dynamically
+        (e.g. CREATE COLLATION), this code should be modified
+        to use mutex locking and to use copy() instead of set().
+      */
+      const char *tailoring;
+      if ((tailoring= my_collation_get_tailoring(id)))
+      {
+        str->set(tailoring, strlen(tailoring), collation.collation);
+        return str;
+      }
+    }
+  case UNKNOWN_PROPERTY:
+    break;
+  }
+  null_value= true;
+  return NULL;
+}
+
+
 void Item_func_weight_string::fix_length_and_dec()
 {
   CHARSET_INFO *cs= args[0]->collation.collation;

=== modified file 'sql/item_strfunc.h'
--- sql/item_strfunc.h	2014-03-26 21:25:38 +0000
+++ sql/item_strfunc.h	2014-05-29 04:50:44 +0000
@@ -1039,6 +1039,49 @@ class Item_func_collation :public Item_s
   table_map not_null_tables() const { return 0; }
 };
 
+class Item_func_collationproperty :public Item_str_func
+{
+  enum Property
+  {
+    UNKNOWN_PROPERTY,
+    TAILORING,
+    USECOUNT
+  };
+  Property cached_property;
+  uint cached_id;
+  Property get_property(Item *item);
+  uint get_id(Item *item);
+  void unknown_collation_warning(const char *arg);
+  /*
+    Check if strings are equal, case insensitively.
+    Strings of different length are quickly considered as non-equal.
+  */
+  bool streq(const String *str, const char *s, size_t length)
+  {
+    DBUG_ASSERT(str->charset()->mbminlen == 1);
+    return str->length() == length &&
+           my_strnncoll(&my_charset_latin1,
+                        (const uchar *) str->ptr(), str->length(),
+                        (const uchar *) s, length) == 0;
+  }
+public:
+  Item_func_collationproperty(Item *a, Item *b) :Item_str_func(a, b),
+    cached_property(UNKNOWN_PROPERTY), cached_id(0) {}
+  String *val_str(String *);
+  const char *func_name() const { return "collationproperty"; }
+  void fix_length_and_dec()
+  {
+    maybe_null= true;
+    collation.set(system_charset_info);
+    max_length= MAX_BLOB_WIDTH * collation.collation->mbmaxlen;
+    if (args[0]->basic_const_item())
+      cached_id= get_id(args[0]);
+    if (args[1]->basic_const_item())
+      cached_property= get_property(args[1]);
+  };
+  table_map not_null_tables() const { return 0; }
+};
+
 class Item_func_weight_string :public Item_str_func
 {
   String tmp_value;


Follow ups