order by cast(%char_val% as unsigned) - откуда берётся warning?

tanglir
Дата: 09.01.2013 11:15:45
Запрос:
select cast('10t' as unsigned) as qwe order by 1
Всё нормально.

А теперь вот такой запрос:
select qwe
from 
 (select cast('10t' as unsigned) as qwe) t0
order by 1
Получаем:
levelcodemessage
Warning1292Truncated incorrect INTEGER value: '10t'

Вопрос: с какого перепоя в интегере появилась строка? Сортировка ведь применяется к уже полученному результату, в котором только одно поле, и оно уже интегер.

ЗЫ. Подумал уже, может, мускль резко "поумнел" и стал пропихивать ордер во внутренний запрос, но эксплейн сказал, что нет
idselect_typetabletypepossible_keyskeykey_lenrefrowsextra
1PRIMARY<derived2>systemNULLNULLNULLNULL1
2DERIVEDNULLNULLNULLNULLNULLNULLNULLNo tables used
, и вот тут я окончательно впал в ступор...
bochkov
Дата: 09.01.2013 12:08:20
чтото мне подсказывает, что вы выложили не весь запрос
потому что при тестировании в верс.4.1,5.1,5.5 варнинга я не увидел.
может плохо искал?
bochkov
Дата: 09.01.2013 12:10:38
кстати сабж 'order by cast(%char_val% as unsigned)' не соответствует представленному запросу
tanglir
Дата: 09.01.2013 12:17:43
bochkov
чтото мне подсказывает, что вы выложили не весь запрос
потому что при тестировании в верс.4.1,5.1,5.5 варнинга я не увидел.
может плохо искал?
весь
версия 5.0.67

автор
кстати сабж 'order by cast(%char_val% as unsigned)' не соответствует представленному запросу
Ага :) То был изначальный вариант, который я в процессе написания поста и разбора причин свёл в конце концов к более простому запросу, выложенному в стартпосте. Но варнинги он выдаёт точно такие же...
Akina
Дата: 09.01.2013 12:19:57
bochkov
может плохо искал?

Logging to file 'e:\mysql_console.log'
Enter password: **********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.27 MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select cast('10t' as unsigned) as qwe order by 1
    -> ;
+-----+
| qwe |
+-----+
|  10 |
+-----+
1 row in set, 1 warning (0.03 sec)

mysql> select qwe
    -> from
    ->  (select cast('10t' as unsigned) as qwe) t0
    -> order by 1
    -> ;
+-----+
| qwe |
+-----+
|  10 |
+-----+
1 row in set, 1 warning (0.03 sec)

mysql> show warnings
    -> ;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: '10t' |
+---------+------+------------------------------------------+
1 row in set (0.00 sec)

mysql>


tanglir
Вопрос: с какого перепоя в интегере появилась строка?

Типы данных в MySQL недостаточно строго типизованы. Т.е. CAST в integer вовсе не приводит к преобразованию строкового вида к бинарно-чисельному, ибо долго, гораздо проще добавить пометку, что значение следует трактовать как типа integer. Но оно при этом не изменяется вовсе. Реальное преобразование выполняется, когда потребуется использование при форматировании к выводу или в вычислениях. А из подзапроса можно передать и так... вот тут-то что-то и теряется...

Думаю. можно смело писать багреп.
Akina
Дата: 09.01.2013 12:22:23
Кстати, странно, что первый запрос у тебя не кидает ворнинга...
Akina
Дата: 09.01.2013 12:39:07
Хотя нет, всё ещё интереснее...

Если покопаться по ману, то warning 1292 встречается там применительно к чисельным значениям всего один раз, в именно в описании функции ASIN(). И там тоже сервер "смотрит вперёд", не выполняя реального преобразования.

Впрочем, это описано уже в примечании к http://dev.mysql.com/doc/refman/5.5/en/cast-functions.html
автор
Posted by anne blankert on May 29 2006 10:14pm

To convert to numeric, the convert() and cast() functions are less forgiving then the implicit conversion when it comes to the data to be converted. If you want to convert "1a" or "1 apple", "2 apples", " 3 things" to 1, 1, 2 and 3 respectivly, the cast and convert function will produce an error. Instead use select 0+'1a', 0+'1 apple', 0+'2 apples', 0+' 3 things'.
tanglir
Дата: 09.01.2013 12:42:52
Akina
Кстати, странно, что первый запрос у тебя не кидает ворнинга...
Как только что выяснилось, первый запрос тоже кидает ворнинг. Если его запускать в кошерном mysql-клиенте.
Однако heidisql загадочным образом показывает, что
select cast('10t' as unsigned) as qwe order by 1;
/* Affected rows: 0 Found rows: 1 Warnings: 0 Duration for 1 query: 0,000 sec. */
То бишь суслик-то есть, но его не видно. А вот ворнинг от второго запроса виден и там, и там.
Сейчас дбфорж ещё потестирую :)
tanglir
Дата: 09.01.2013 12:44:40
Akina
Впрочем, это описано уже в примечании
Во, спасибо.
tanglir
Дата: 09.01.2013 12:49:53
А дбфорж вообще давит все ворнинги. Оба запроса выполнены без всяких предупреждений. Может, правда, это дефолтные настройки там такие.