22.11.2014

Мускул и Йожег

Ну вот, по роду своей деятельности пришлось столкнуться вот с этими зверьками. Надо сказать, что они мне понравились.
MySQL существенно улучшился за последние несколько лет. Позволяет, по сравнению с Interbase, делать очень интересные запросы. И работает ничего так себе, быстро достаточно. Ну, конечно, есть пара нюансов, которые удивляют. Так вот, я о них :)

Первое, это конкатенация слов. Вроде бы есть стандарт SQL, но по умолчанию используется другой механизм. А отказ от стандарта -  ради "насильников". :) Поэтому приходится использовать функцию для соединения строк, вместо оператора. Хотя оператор, предлагаемый стандартом SQL, тоже несколько странный.

Вторая особенность - это логические операции. Сразу видно, что в Мускул они пришла из мира "насильников". Возможно, даже "гнусных". :)
Идея в том, что значение любого типа может трактоваться как логическое, а логическое, на самом деле, это целое. 0 означает "ложь", а все остальное - "истину". Стандартно логические условия в качестве истины возвращают единицу.
В результате можно мутить вот такие вот выражения:

salary*tax*(salary>1000).

Здесь мы рассчитываем налог на зарплату, при условии, что она больше 1000. Если меньше 1000, то налог равен нулю. В соответствии с требованиями стандарта такое выражение пришлось бы писать по-другому. Например, так:

case when salary > 1000 then salary*tax else 0 end

Конечно, первый подход гораздо эффективней и компактней. Но! Как легко же сделать ошибку. В частности, я наткнулся один раз. Начал писать условия в разделе where, отвлекся на что-то и получилось что-то вроде

where stype=1 and mode

После mode подразумевалось дописать условие. Но так как я отвлекся, то, вернувшись к задаче, дописать забыл. И в Мускуле это не ошибка, а вполне легальная запись логического выражения, так как любое значение может трактоваться как логическое. Так что будьте осторожны. Правильное условия выглядело примерно так:

where stype=1 and mode=4

Йожег тоже поразил. Включенной по умолчанию настройкой, которая перед сохранением редактируемого строкового поля в "гриде" пытается его сначала выполнить. Типа, а вдруг там какое-то SQL выражение. И если там вдруг правда оказалось SQL-выражение, то в поле будет записан результат его вычисления.
Это сделано для того, что бы пользователь мог что-то выполнить. Честное слово, руки бы отрывал. :)
Но есть нюасн: вычисляются многие выражения, но не CASE. Не понятно, что за прикол, то ли ошибка, то ли фича такая.
В общем, тоже словил косяк на пустом месте. Потому как не ожидал такой гадости от порядочной программы. Хотя меня предупреждали о такой вот занимательной особенности Йожега.

02.11.2014

Строковый хэш

Наконец-то появилось немножко свободное время. Поэтому решил развлечься. Потренироваться в программировании.
Люблю писать маленькие, совершенно бесполезные и никому не нужные программки. Вот и сейчас, в продолжении предыдущего поста, решил продемонстрировать сам себе, как оно может работать. Естественно, в код обязательно для пущего самоудовлетворения вставляются ассемблерные вставки.
В общем, в формочку надо ввести предложение данные, только на русском языке. Потому что такой дебильный вариант закона о персональных данных только у нас. :) Все приводится к верхнему регистру.
После чего формируется строка, из которой удаляются шумовые символы (пробелы и точки, другие шумовые символы ввести нельзя). Далее это строка по простейшему алгоритму перемешивается. Перемешивание зависит только от самой строки.
После этого происходит расчет хэш-суммы в виде 32-разрядного целого по простейшей схеме, примерно такой:
Sum := Sum*S[i]+S[i].
Недостаток такого подхода состоит в том, что при сколько-нибудь значительно длине строки происходит переполнение 32-разрядного целого, и, таким образом, в формировании хэша участвует только несколько последних символов строки. А начало строки "забывается" алгоритмом.
Что бы избежать этого, старшая часть 64 числа после умножения регулярно складывается с младшей.
Ну и можно указать начальное значение для переменной Sum (поле "Смещение"), это аналог "соли" во избежание быстрого подбора хэша по словарю.
Ну и конечно, в вырожденном случае, когда длина всех символьных полей оказывается мала (то есть все текстовые поля состоят из одной буквы), хэш функция вырождается. Но, я думаю, такое маловероятно с учетом особенностей русского языка. :)
Если что, алгоритм работает с ANSI кодировкой, в принципе, никто не мешал мне использовать UNICODE, но заморачиваться не охота.
Впервые попробовал делать 64-разрядные вставки на ассемблере. Это классно! Дополнительные регистры и 64-разрядные арифметические операции существенно сокращают и упрощают код. Я бы вообще Intel'овскую архитектуру запретил законодательно. :) да здравствует RISC!
Да, программка здесь, если кому в голову придет безумная идея ее запустить.