Доброго времени суток!
DAX 2009 (application version 5.0.1000.52)
Наблюдается некоректное поведение функции
Global::record2DynaKey, если в
первичном ключе таблицы, есть поле типа
UtcDateTime, в этом случае строковый ключ строится неправильно, как следствие, использование обратной функции
Global::dynaKey2Record, не приводит к ожидаемому результату.
Видимо реализация метода
Global::record2DynaKey должна быть примерно такой(сделано по аналогии с типом Date) :
X++:
static str record2DynaKey(Common rec)
{
tableId tableId = rec.TableId;
DictTable dictTable = new DictTable(tableId);
indexId indexId = dictTable.indexUnique();
DictIndex dictIndex = dictTable.indexObject(indexId);
str buf;
int indexCnt;
int fieldsInIndex;
fieldId fieldId;
str any2strLocal(anytype t)
{
return t;
}
if (dictIndex.name() == 'RecId') // RecId as index
return '['+int2str(fieldnum(Common,RecId))+':'+int642str(rec.RecId)+']';
else
{
fieldsInIndex = dictIndex.numberOfFields();
for (indexCnt = 1; indexCnt <= fieldsInIndex; indexCnt++)
{
fieldId = dictIndex.field(indexCnt);
buf += '[' + int2str(fieldId) + ':';
switch (typeof(rec.(fieldId)))
{
case Types::Date:
buf += date2str(rec.(fieldId),-1,-1,-1,-1,-1,-1, DateFlags::None);
break;
//SRF -->
case Types::UtcDateTime :
buf += datetime2str(rec.(fieldId), DateFlags::None);
break;
//SRF <--
default:
//buf += any2StrLocal(strReplace(rec.(fieldId),' ', '%20'));
buf += any2StrLocal(rec.(fieldId));
}
buf += ']';
}
if (dictIndex.allowDuplicates())
{
buf += '['+int2str(fieldnum(Common,RecId))+':'+int642str(rec.RecId)+']';
}
}
return buf;
}
По той же причине, проблемы могут возникнуть и в методе
buildIndexStr класса
SysDataSearchIndexBuilder, реализация примерно следующая :
X++:
private str buildIndexStr(Common record, List listFieldIds)
{
fieldId fieldId;
str ret;
TextBuffer thisStr = new TextBuffer();
Integer i, nWords;
anytype thisFieldValue;
str any2strLocal(anytype t)
{
return t;
}
;
enum.reset();
while (enum.moveNext())
{
fieldId = enum.current();
switch (typeof(record.(fieldId)))
{
case Types::Date:
ret += date2str(record.(fieldId),-1,-1,-1,-1,-1,-1);
listFieldIds.addEnd(fieldId);
break;
//srf -->
case Types::UtcDateTime :
ret += datetime2str(record.(fieldId));
listFieldIds.addEnd(fieldId);
break;
//srf <--
default:
thisFieldValue = record.(fieldId);
thisStr.setText(any2StrLocal(thisFieldValue));
ret += thisStr.getText();
// Repeat the field ID once per word:
nWords = SysSearch::splitIntoWords(thisStr).elements();
for (i = 0; i < nWords; ++i)
{
listFieldIds.addEnd(fieldId);
}
}
ret += #DELIMITER;
}
ret += tablelabel;
// Search for the table label as well.
return ret;
}
Оба метода используют локальную функцию
any2strLocal для преобразования, любого типа в строку, однако для типа данных
UtcDateTime - данная функция возвращает пустое значение.
P.S. Во вложении проект, эмитирующий данную ситуацию. В нем 1 таблица, 2 джоба и 2 класса(Global и SysDataSearchIndexBuilder, изменения аналогичны написаным в теме, но закоментарены).
job SRF_FindUtcDateTimeTypeInUniqueIndex - выводит список таблиц, в которых в первичном ключе есть поле типа UtcDateTime(в стандарте нашел порядка 10 таких таблиц)
job SRF_TestRecord2DynaKey - эмитирует ошибку функции Global::record2DynaKey. Для того, чтобы пронаблюдать данный эффект в импортируемой таблице создайте одну запись, запустите job, затем внесите изменения в Global и вновь запустите job.