diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index b811a27203c7ec773a2c7c2035e96b439396e518..45cdc6a2101b024afeb7fdd7b86d1e570cf0fe49 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1560,6 +1560,15 @@ execute stmt;
 ERROR 42S22: Unknown column 'y.value' in 'field list'
 deallocate prepare stmt;
 drop tables t1;
+prepare stmt from "create table t1 select ?";
+set @a=1.0;
+execute stmt using @a;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `?` decimal(2,1) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
 End of 5.0 tests.
 create procedure proc_1() reset query cache;
 call proc_1();
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 1fd1cc4a405470757a7f31c5621b347238021ac3..c6aa05df900d30db26072778e27b4f270d243095 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -1626,6 +1626,14 @@ execute stmt;
 deallocate prepare stmt;
 drop tables t1;
 
+#
+# Bug #28509: strange behaviour: passing a decimal value to PS
+#
+prepare stmt from "create table t1 select ?";
+set @a=1.0;
+execute stmt using @a;
+show create table t1;
+drop table t1;
 
 --echo End of 5.0 tests.
 
diff --git a/sql/item.cc b/sql/item.cc
index 24958f64f2aca79e6c2eebba49a07e9a2ebcf8d8..8f59e8a3e042e1311a0e8832bcd97fd61dc81c32 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2542,16 +2542,14 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
   if (entry && entry->value)
   {
     item_result_type= entry->type;
-    switch (entry->type) {
+    switch (item_result_type) {
     case REAL_RESULT:
       set_double(*(double*)entry->value);
       item_type= Item::REAL_ITEM;
-      item_result_type= REAL_RESULT;
       break;
     case INT_RESULT:
       set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS);
       item_type= Item::INT_ITEM;
-      item_result_type= INT_RESULT;
       break;
     case STRING_RESULT:
     {
@@ -2574,7 +2572,6 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
         charset of connection, so we have to set it later.
       */
       item_type= Item::STRING_ITEM;
-      item_result_type= STRING_RESULT;
 
       if (set_str((const char *)entry->value, entry->length))
         DBUG_RETURN(1);
@@ -2588,6 +2585,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
       decimals= ent_value->frac;
       max_length= my_decimal_precision_to_length(ent_value->precision(),
                                                  decimals, unsigned_flag);
+      item_type= Item::DECIMAL_ITEM;
       break;
     }
     default: