View Issue Details

IDProjectCategoryView StatusLast Update
0007893VCOMPONENT-VKERNELSQLpublic2017-03-01 09:57
ReporterVladimir Esipov Assigned ToIvan Smahin  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
PlatformINTELOSWindowsOS Version7
Product Version7.0 
Fixed in Version7.0.x 
Summary0007893: Inconsistency documentation functions FLOOR, CEIL, TRUNC, ROUND and others...
DescriptionВ доках к VDB описано, что функции CEIL и FLOOR должны возвращть результат в виде целого, что вполне ожидаемо, т к. это стандартная реализация в Си -> в SQL от Postgre, Oracle, Mysql и т.д..
По-факту, эти функции возвращают число двойной точночти:

    SELECT CEIL(1.23) --> 2.000000 вместо 2
    SELECT FLOOR(-1.23) --> -2.000000 вместо -2

Функция ROUND вроде должна выполнять округление, не меняя тип результата

    SELECT ROUND(-1.586,2) --> -1.590000 вместо -1.59
    SELECT TRUNC(1.223,1) --> 1.200000 вместо 1.2

Если подобное поведение является неизбежной и запланированной особенностью VDB, возможно следует внести изменения в раздел документации
http://valentina-db.com/docs/dokuwiki/v7/doku.php?id=valentina:vcomponents:vsql:reference:expr:funcs_numeric, указав, что функции возвращают Double или же привести работу функций к более привычному виду.
TagsNo tags attached.

Activities

Ivan Smahin

Ivan Smahin

2017-02-28 09:22

developer   ~0009480

ceil/floor возвращают double в С++

http://www.cplusplus.com/reference/cmath/ceil/
http://stackoverflow.com/questions/1253670/why-do-round-and-ceil-not-return-an-integer

но, по крайней мере, MySQL возвращает int.
Ок, мы тоже будем возвращать int, как и заявлено в документации.

ROUND/TRUNC возвращают double. Я не вижу разногласий с документацией.
Более подробно - в данном контексте результатом этих функций будет поле типа double. И далее:

I_Value_Ptr pValue = pFld->get_Value(); // Actually it is Value_double.

Теперь, можно получить значение как double:
double val = pValue->get_Double();

А можно получить строковое представление этого значения:
String val = pValue->get_String();
// val == "-1.590000"

В последнем случае на результат будут влиять Scale/Precision для этого поля/value.
Например:

I_ValueApproximate_Ptr pVal2 = QI(pValue, I_ValueApproximate);
pVal2->put_Scale(2);

String val = pValue->get_String();
// val == "-1.59"
Vladimir Esipov

Vladimir Esipov

2017-02-28 16:21

reporter   ~0009488

-- ROUND/TRUNC возвращают double. Я не вижу разногласий с документацией.

Иван, может быть я не прав, но, пожалуйста, присмотрись внимательней к мануалу:

    TRUNC (X,D)
    Returns the number X, truncated to D decimals.
    If D is 0, the result will have no decimal point or fractional part.
    If D is negative, the integer part of the number is zeroed out.

или http://oracleplsql.ru/trunc-function-for-number.html

То бишь, суть TRUNC в том, что она должна в возвращаемом результате УСЕКАТЬ количество знаков после запятой в соответствии с необязательным параматром D:

    SELECT TRUNC(123.466, 2) должна вернуть 123.46, а не 123.460000

если D не задан, D=0 , т.е:

    SELECT TRUNC(123.466) должна вернуть 123, а не 123.000000

По CEIL и FLOOR - может быть, оставить всё как есть, а только внести коррективу в вики?
Все таки "break-change", возможно, кто-то их уже юзает в проектах... Вот они "обрадуются"!

Вообще, я эту тему зацепил ещё и потому, что не нашел простого способа привидения double к int средствами SQL. Вроде нет такой функции..
Может быть, всё-таки добавите на уровне SQL функции конверсии, хотя бы ToInt()?

PS Открытые мной тикеты с 0007020 по 0007023 по VCDK пожалуй можно погасить. Вроде всё ОК.
Ivan Smahin

Ivan Smahin

2017-03-01 07:47

developer   ~0009492

По CEIL и FLOOR - может быть, оставить всё как есть, а только внести коррективу в вики?
Все таки "break-change", возможно, кто-то их уже юзает в проектах... Вот они "обрадуются"!

На самом деле это мало кого может затронуть.
Я выше писал, что цепочка здесь примерно такая на примере CEIL() - эта функция заявлена уже как возвращающая int. В контексте "SELECT CEIL(...)..." в курсоре будет создано поле Field_LLong (соответственно value у него Value_llong). У любого value определены методы get_Long(), get_LLong(), get_Double(), get_String() .... Т.е. спросив get_double() получим ровно то как было раньше - здесь не сыграет роли что мы получили Value_llong а не Value_double как было до этого изменения.
И ранее, когда функция была заявлена как возвращающая double тоже можно было бы спросить Value_double::get_Long() и получить целочисленный ответ.

vStudio спрашивает всегда (точнее в большинстве случаев) get_String(), как наиболее универсальный метод представления значения. Вот тут будет разница в ответе. Но, с другой стороны, немного таких случаев, когда в приложении намеренно получают String, а потом трактуют сами его как double/int/... когда можно сразу получить желаемое.
Ivan Smahin

Ivan Smahin

2017-03-01 07:50

developer   ~0009493

по ROUND/TRUNC - документацию поправим чтобы не было разногласий. Эти функции всегда возвращают double.
Ivan Smahin

Ivan Smahin

2017-03-01 07:52

developer   ~0009494

В качестве toInt() теперь можно воспользваться CEIL()/FLOOR()

SELECT FLOOR( 1.123 )
=> 1

SELECT CEIL( 1.123 )
=> 2

Issue History

Date Modified Username Field Change
2017-02-25 05:22 Vladimir Esipov New Issue
2017-02-28 09:22 Ivan Smahin Note Added: 0009480
2017-02-28 09:24 Ivan Smahin Status new => resolved
2017-02-28 09:24 Ivan Smahin Fixed in Version => 7.0.x
2017-02-28 09:24 Ivan Smahin Resolution open => fixed
2017-02-28 09:24 Ivan Smahin Assigned To => Ivan Smahin
2017-02-28 16:21 Vladimir Esipov Note Added: 0009488
2017-02-28 16:21 Vladimir Esipov Status resolved => feedback
2017-02-28 16:21 Vladimir Esipov Resolution fixed => reopened
2017-03-01 07:47 Ivan Smahin Note Added: 0009492
2017-03-01 07:50 Ivan Smahin Note Added: 0009493
2017-03-01 07:52 Ivan Smahin Note Added: 0009494
2017-03-01 09:57 Ivan Smahin Status feedback => resolved
2017-03-01 09:57 Ivan Smahin Resolution reopened => fixed