AVRIL_START_JANCOKALIVEAVRIL_END_JANCOK Interactive Terminal

Command Executor

IBProvider Developer's Blog

XSQLVAR::sqltype и XSQLVAR::sqlind

Привет всем.

В ISC API, для представления описаний и значений колонок (параметров запроса), определена структура XSQLVAR.

typedef struct
{
 ISC_SHORT  sqltype;          /* datatype of field */
 ISC_SHORT  sqlscale;         /* scale factor */
 ISC_SHORT  sqlsubtype;       /* datatype subtype - currently BLOBs only */
 ISC_SHORT  sqllen;           /* length of data area */
 ISC_SCHAR* sqldata;          /* address of data */
 ISC_SHORT* sqlind;           /* address of indicator variable */
 ISC_SHORT  sqlname_length;   /* length of sqlname field */
 ISC_SCHAR  sqlname[32];      /* name of field, name length + space for NULL */
 ISC_SHORT  relname_length;   /* length of relation name */
 ISC_SCHAR  relname[32];      /* field's relation name + space for NULL */
 ISC_SHORT  ownname_length;   /* length of owner name */
 ISC_SCHAR  ownname[32];      /* relation's owner name + space for NULL */
 ISC_SHORT  aliasname_length; /* length of alias name */
 ISC_SCHAR  aliasname[32];    /* relation's alias name + space for NULL */
} XSQLVAR; 

Идентификатор типа указывается в поле XSQLVAR::sqltype и в случае NOT NULL колонки представляет собой четное число. Для Firebird 2.5 определен следующий набор идентификаторов типов данных:

#define SQL_TEXT         452
#define SQL_VARYING      448
#define SQL_SHORT        500
#define SQL_LONG         496
#define SQL_FLOAT        482
#define SQL_DOUBLE       480
#define SQL_D_FLOAT      530
#define SQL_TIMESTAMP    510
#define SQL_BLOB         520
#define SQL_ARRAY        540
#define SQL_QUAD         550
#define SQL_TYPE_TIME    560
#define SQL_TYPE_DATE    570
#define SQL_INT64        580
#define SQL_NULL       32766

В случае колонок, которые могут принимать значение NULL, к идентификатору типа данных добавляется единица.

Само значение индикатора NULL-состояние доступно по указателю XSQLVAR::sqlind. Минус один (-1) для NULL и ноль (0) для NOT NULL состояния.

Если идентификатор типа (XSQLVAR::sqltype) описывает обнуляемый тип, то XSQLVAR::sqlind должен содержать ненулевой указатель. Иначе возникнут проблемы.

Если идентификатор типа (XSQLVAR::sqltype) описывает NOT NULL колонку, то XSQLVAR::sqlind игнорируется.

Вот здесь мы подошли к вопросу, который регулярно появляется в моей голове, когда я вожусь с этим самым «XSQLVAR::sqlind»:

Какому гению пришло в голову увязывать наличие/отсутствие индикатора NULL-состояния (sqlind) значения с описанием типа (sqltype)?

Это же две несвязанные вещи!
(далее…)

Поддержка массивов в IBProvider

Привет всем.

На сайт выгружен новый триал IBProvider v3.28 с собственным механизмом чтения/записи массивов базы данных. Как я тут уже ранее писал — все это затеяно ради исправления бага с VARCHAR-массивами. Вкратце — клиент вместо VARCHAR-массивов должен был работать с CSTRING-массивами.

Исправление доступно только для серверов (FB/IB/YA), работающих на Windows (winnt_x86, winnt_amd64). Для остальных операционных систем и процессоров будет задействован старый добрый ISC API с одним ограничением — без поддержки чтения/записи VARCHAR-массивов.

Если есть пожелание добавить другие платформы — напишите, добавлю. Здесь только одна проблема — нужно будет прогнать тесты.

Настройка

По умолчанию, провайдер сам выбирает подходящий режим чтения/записи массивов с учетом платформы сервера и ODS базы данных.

Процессом выбора можно порулить с помощью нового свойства инициализации — «array_rw_mode». Допустимые значения: «api» или «direct».

Настройка распространяется на все колонки с массивами. Выборочная настройка для отдельных колонок не доступна.

Отмечу, что в случае IB7.1+ новый механизм нужно включать явно. По умолчанию, провайдер будет работать через ISC API. Это связано с шифрованием содержимого колонок, которое IBProvider, понятное дело, обеспечить не может.

Для FB (на Windows, x86/amd64), по умолчанию, будет использоваться новый механизм.

Это точно работает правильно?

Собственный механизм чтения/записи массивов был проверен практически на всех выпущенных версиях FB/IB. В том числе и с помощью перекрестных проверок.

Немного о внутренностях

Массивы в базе данных хранятся в блобах. Так что, новый механизм — это код, напрямую работающий с этими блобами.

Счастье наступило?

Лично для меня — да.

А в целом — нет. Потому что gbak работает через ISC API и, соответственно, он не сможет правильно сохранить и восстановить VARCHAR-массивы. Но это уже другая история.

«NEWS»: Firebird/Java Engine Plug-in in development

By fact, it is BREAKING NEWS!

facepalm
Adriano читает firebirdnews.org

PS. По моему, это как раз тот случай, когда надо сначала перепрыгнуть…

Дежавю

Привет Типа утро доброе.

Подошел Приполз утром к компьютеру.

И слышу характерное «плям!».

Напрягся.

[16.02.2016 23:01:19] [info] Provider DLL    :_IBProvider_v3_vc14xp_w64_d.dll
[16.02.2016 23:01:19] [info] Provider Version:3.27.3.20014
[16.02.2016 23:01:19] [info] Server Name     :Firebird
[16.02.2016 23:01:19] [info] Server Version  :3.0.0.32332
[16.02.2016 23:01:19] [info] Client Name     :Firebird
[16.02.2016 23:01:19] [info] Client Version  :3.0.0.32332
[16.02.2016 23:01:19] [info] Database ODS    :12.0
[16.02.2016 23:01:19] [info] Database Dialect:3
....
[17.02.2016 07:11:03] [Thread #2] [START  ] rowset.asynch.003.cancel_active_loader.read_only.random_access_v1.non_blocking_fetch.fetch_first_row.reexec_1 [#120]
Assertion (statement->haveException() == 0) failure: ..\..\..\src\remote\client\interface.cpp 2278

Про FB API

Привет всем.

Случайно обнаружил следующую вещь в исходниках Firebird:

firebird\branches\B2_0_Release\src\jrd\inf_pub.h:

isc_info_db_impl_sun_amd64 = 71, //появился в FB2.0.5

firebird\branches\B2_1_Release\src\jrd\inf_pub.h:

isc_info_db_impl_linux_mipsel = 71, //появился в FB2.1.0
isc_info_db_impl_sun_amd64 = 74, //появился в FB2.1.1

Вздрогнул и полез проверять стабильность идентификаторов в рамках пакетов исправлений.

Меня терзают смутные сомнения…

Привет всем.

В Firebird 2.0 был исправлен алгоритм вычисления размера буфера (XSQLVAR::sqllen) текстовых колонок (CHAR/VARCHAR) — он начал учитывать кодовую страницу подключения. Спасибо Adriano dos Santos Fernandes.

Здесь были чертыхания по поводу кодовой страницы блоба и XSQLVAR::sqlscale

До этого (а в InterBase до сих пор), размер буфера под значение вычислялся как количество символов в столбце умноженное на максимальное количество байт в одном символе кодовой страницы столбца.

Проблема, к примеру, проявляется при попытках прочитать столбца с кодовой страницей WIN1251 в подключении с кодовой страницей UTF8. Вылазит ошибка «Arithmetic exception, numeric overflow, or string truncation».

Я как-то пробовал подсовывать серверу правильно вычисленное значение буфера в XSQLVAR::sqllen, но он там внутри у себя все равно использовал буфер с неправильным размером.

Но недавно появилась мысль — а если попробовать работать не с XSQLDA, а непосредственно с MSG-буфером, где появляется возможность использования таких волшебных типов BLR-типов данных как varying2 и text2, для которых можно указать кодовую страницу?

Если сервер сможет вернуть клиенту текстовые данные без приведения к кодовой странице подключения, то это автоматически решит обозначенную проблему с переполнением буфера. Привести текстовые данные к кодовой странице подключения я могу и сам.

Во какая мысль.

Пожалуй, я её попробую покопать поглубже сразу после того как допилю новый код для работы массивами.

UPD1.
Мысль, наверное, не совсем правильная. Нужно сначала попробовать varying2/text2 с указанием кодовой страницы подключения и правильного размера буфера под данные. Может прокатит.

Выпущен IBProvider v3.27.1

Привет всем.

Асилил. На этом будем считать, что марафон с v3.27 завершен.

Сейчас надо собирать мозги в кучу и допиливать исправление для CORE-1588.

Потом нас ждут другие, по настоящему интересные задачи.

Понравилась статья на хабре — «Восход разработчикономики»

Привет всем.

В последнее время утомляется чтение как художественной так и технической литературы. Особенно когда рядом есть рабочий компьютер (в смысле, компьютер на котором я работаю). Появляется мысль «Н@#&р, лучше пойти повозиться с кодом. Любым». У меня его на любой вкус и цвет уже — навалом.

Так что прочитанной статье можно сказать повезло.
1. Я сегодня достаточно удолбался выполнять роль отца семейства, чтобы оставить надежду вечером повозиться «со своей прелестью» хотя бы пару часов.
2. На компьютерах работают тесты, которые жалко не то чтобы прерывать, а даже приостанавливать.

Первая часть.
Вторая часть.

Лет двадцать назад я бы даже и не понял о чем в ней написано.

А сейчас («сидя в уютном доме, в приличном районе») могу сказать, что моя семья сделала правильные инвестиции.

—-
Впрочем, лично меня сейчас гораздо больше забавляет то, как моя гора кода, созданная за последнее десятилетие, достаточно без проблем эволюционирует и приспосабливается к моим безбашенным идеям 🙂

—-
UPD. Клиенты, надеюсь уверен, тоже неплохо вложились…

Костыли для типа данных «массив»

Привет всем.

На днях провел эксперименты, проверяющие работоспособность внешнего исправления для ошибки сервера (FB/IB) — CORE-1588.

Краткое описание ошибки — сервер получает и возвращает VARCHAR-массивы как CSTRING-массивы.

К счастью, этот баг имеет ограниченную область действия — в базу, в конечном итоге, пишутся VARCHAR-массивы. Это можно проверить поэлементным чтением VARCHAR-массивов.

Решение, как и было предположено ранее, заключается в самостоятельном формировании блоба массива.

Извращение, конечно. Хотя бы потому, что нужно учитывать тип процессора, на котором работает сервер базы данных. Эти сведения можно получить через информационное свойство «isc_info_implementation».

Самое приятное то, что в сервере предусмотрена лазейка для этого варварского внешнего формирования блоба с данными массива.

Будет интересно соорудить весь необходимый код и посмотреть на его работу.

Релиз IBProvider v3.27. Краткий итог.

Привет всем.

Собственно subj.

Последние несколько недель я размышлял над всем этим процессом и сейчас можно подвести некоторые итоги.

От начала до конца — чуть больше года. Эффективный объем времени, совпадает с начальным прогнозом — 6 месяцев. Остальное время съели релиз ADO.NET провайдера, перевод сайта на WordPress (грустно вздохнул) и другие процессы реальной жизни.

Немножко ошибся с оценкой объема исходного кода подсистемы. Думал уложиться в 800KB. Получилось 1.7MB. Учту на будущее. Впрочем, я думал что код будет компактным, но сложным. А он оказался (в конечном итоге) прямолинейным и объемным.

Объем исходных текстов модульных тестов — 3.7MB. Соотношение 1:2, в последнее время, стало нормой. Всего генерируется 24K тестов. Основной «мультипликатор» — 4 режима протокола соединения (rpc, batch_send, out_of_band, lazy_send).

32-х битная DLL провайдера увеличилась где-то на 670 килобайт. Это больше чем «весит» fbclient.dll. 200KB сожрали ресурсы с шаблонами сообщений серверных ошибок (английский и русский).

Нагрузочное тестирование показывает, что IBProvider при работе через встроенного клиента поедает на 5% процентов процессорного времени меньше, чем через fbclient.dll. А реальное время работы — вообще не поменялось. В целом, здесь сложно ожидать чуда. Код стал немного «умнее», но увеличилось количество проверок. Все, что приезжает из сети, теперь проверяется самым тщательным образом.
(далее…)