powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / баг?
23 сообщений из 23, страница 1 из 1
баг?
    #39026406
ZZTor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SS 2.5.4 26856, 2.5.3 было тоже самое.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create or alter procedure GET_SCRIPT_PATH_TEST
returns (
    PATH varchar(1024),
    PATH2 varchar(1024),
    RES varchar(1024))
AS
 declare variable parent_id integer;
 declare variable script varchar(1024);
begin
 script = 'test';
 path = '';
 path2 = '';
 path = script||trim(iif(path<>'','\',''))||path;
 path2 = script||iif(path2<>'','\','')||path2;
 res = '~'||path||'~'||'~'||path2||'~';
 suspend;
 if (path<>path2) then begin
  res = 'err';
  suspend;
 end
end


Результат: res=~test~~test ~
Откуда взялся пробел? И почему тогда if не срабатывает?
...
Рейтинг: 0 / 0
баг?
    #39026415
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZZTorОткуда взялся пробел?
Из типа данных CHAR(), который имеют все строковые литералы. STFF.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
баг?
    #39026418
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZZTorИ почему тогда if не срабатывает?См. сравнение строковых литералов.
Хочешь сравнение с пробелами - ставь LIKE.
...
Рейтинг: 0 / 0
баг?
    #39026693
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
WildSeryZZTorИ почему тогда if не срабатывает?См. сравнение строковых литералов.
Хочешь сравнение с пробелами - ставь LIKE.
Это не сравнение строковых литералов.
Это потому что функция iif возвращает тип CHAR(N), а N выбирает как максимум длин второго и третьего параметра.
А тип CHAR в параметрах, как правильно отметил Dimitry Sibiryakov, получился именно потому что в FB строковые константы имеют тип CHAR(N).

Пустая строка '' будет иметь тип CHAR(0), хотя сам такой тип описать не удастся.

Ещё пример:
Код: sql
1.
select iif(0=0, cast('' as VARCHAR(10)), 'dddddddddddddddddddd') from rdb$database

Тут тип (VARCHAR) берётся из одного параметра (с типом VARCHAR(10)), а длина из другого (с типом CHAR(20)).
Итого имеем VARCHAR(20).
...
Рейтинг: 0 / 0
баг?
    #39026704
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
fb userWildSeryпропущено...
См. сравнение строковых литералов.
Хочешь сравнение с пробелами - ставь LIKE.
Это не сравнение строковых литералов.
Хотя да, это ещё и сравнение варчаров. Я всё ещё не могу поверить в то, что можно было так реализовать сравнение.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select 
  iif(
    cast('A' as varchar(10)) = cast('A   ' as varchar(10)), 
    'противоестественно равны', 
    'естественно не равны'
  )
from rdb$database
--
противоестественно равны



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select 
  iif(
    character_length(cast('A' as varchar(10))) = character_length(cast('A   ' as varchar(10))), 
    'противоестественно равны', 
    'естественно не равны'
  )
from rdb$database
--
естественно не равны


Ну и естественно нельзя в unique varchar-поле вписать 'A' и 'А ', т.к. эти значения равны.
А дальше немного неконсистентно:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
CREATE TABLE T (
    V  VARCHAR(10),
    X  INTEGER
);

INSERT INTO T (V, X) VALUES ('ww', 1);
INSERT INTO T (V, X) VALUES ('ww ', 1);

select V, sum(X) from T group by 1
-- ok
'ww', 2

select distinct(V) from T
-- ok
'ww'

-- Вот исключение из правил:
select T1.V from T T1 inner join T T2 on (T1.V = T2.V)
-- not ok
'ww'
'ww '
-- Почему так? По закону должно быть четыре записи. 
-- Вот так их четыре:
select T1.V from T T1 inner join T T2 on (T1.V = 'ww ')


-- А после 
update T set V = 'ww';
-- недостающие записи появляются и в таком запросе:
select T1.V from T T1 inner join T T2 on (T1.V = T2.V)
--
'ww'
'ww'
'ww'
'ww'


Получается что в inner join иногда 'ww' <> 'ww ', а иногда 'ww' = 'ww '.
...
Рейтинг: 0 / 0
баг?
    #39026725
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Способ сравнения строк зависит от коллайта. По умолчанию во всех колейтах оно не чувствительно к завершающим пробелам. Это кстати так стандарт диктует. Но если ты уж сильно хочешь чтобы конечные пробелы учитывались, то это можно сделать. См. оператор CREATE COLLATION опции [NO PAD | PAD SPACE]

fb user
Код: sql
1.
2.
3.
4.
5.
-- Вот исключение из правил:
select T1.V from T T1 inner join T T2 on (T1.V = T2.V)
-- not ok
'ww'
'ww '



На какой версии сервера пробовал? Если на тройке, то подозреваю, что тут HASH JOIN немного не так отработал.
...
Рейтинг: 0 / 0
баг?
    #39026752
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов ДенисНа какой версии сервера пробовал?
На снапшоте тройки. На 2.5 всё хорошо.
...
Рейтинг: 0 / 0
баг?
    #39026768
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов ДенисНо если ты уж сильно хочешь чтобы конечные пробелы учитывались, то это можно сделать. См. оператор CREATE COLLATION опции [NO PAD | PAD SPACE]
И просто указать этот COLLATION в DECLARE VARIABLE? И в примере из первого поста сравнение "if (path<>path2)" заработает как нужно?
А если этот COLLATION назначить дефолтным, то можно его для переменных не указывать?
И даже конструкции без переменных, вроде "cast('A' as varchar(10)) = cast('A ' as varchar(10))" заиспользуют этот COLLATION?
...
Рейтинг: 0 / 0
баг?
    #39026790
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb userСимонов ДенисНа какой версии сервера пробовал?
На снапшоте тройки. На 2.5 всё хорошо.

это бага HASH JOIN. В 2.5 для этого запроса используется MERGE JOIN. Скорее всего вычисляется хэш от необработанной строки. Хеши дают разные результаты придёт dimitr скажет точнее. А может пошлёт в трекер.
...
Рейтинг: 0 / 0
баг?
    #39026793
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

ну так попробуй. Ты же уже столько экспериментов тут наставил чтобы показать странности.
...
Рейтинг: 0 / 0
баг?
    #39026800
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE COLLATION UTF8_NOPAD
FOR UTF8
FROM UNICODE
NO PAD;

SELECT
  'a' = 'a ' as s1,
  'a' collate UTF8_NOPAD = 'a ' collate UTF8_NOPAD as s2
FROM rdb$database;



Код: plaintext
1.
2.
s1       s2
----------------
true    false
...
Рейтинг: 0 / 0
баг?
    #39026837
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис,

Код: sql
1.
2.
3.
4.
5.
6.
CREATE COLLATION WIN1251_NOPAD
FOR WIN1251
FROM WIN1251
NO PAD;

alter database set DEFAULT CHARACTER SET win1251;

как default collation для базы сменить?
Я как только не пытался:
Код: sql
1.
2.
3.
alter database set DEFAULT CHARACTER SET win1251 collation WIN1251_NOPAD; -- по аналогии с CREATE DATABASE
alter database set DEFAULT collation WIN1251_NOPAD;
alter database set collation WIN1251_NOPAD;
...
Рейтинг: 0 / 0
баг?
    #39026839
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

для базы никак. Можно изменить для чарсета. См. оператор ALTER CHARACTER SET
Для трёшки можно изменить чарсет для БД по умолчанию, но не коллейт.
...
Рейтинг: 0 / 0
баг?
    #39026841
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Понял, оказывается collation в CREATE DATABASE - это не collation для базы, а дефолтный collation для чарсета.
Поэтому меняется так:
Код: sql
1.
alter character set WIN1251 set default collation WIN1251_NOPAD
...
Рейтинг: 0 / 0
баг?
    #39026848
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb userСимонов ДенисНа какой версии сервера пробовал?
На снапшоте тройки. На 2.5 всё хорошо.

вообще-то у меня на 2.5.5 тоже воспроизводится. Это бага в методах соединения HASH/MERGE JOIN. Ибо стоит создать индекс и поведение меняется с точностью до наоборот. Или заменить JOIN на LEFT JOIN.

твой эксперимент

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
RECREATE TABLE T (
    V  VARCHAR(10),
    X  INTEGER
);

INSERT INTO T (V, X) VALUES ('ww', 1);
INSERT INTO T (V, X) VALUES ('ww ', 2);

COMMIT;

--CREATE INDEX IDX_T_V ON T(V); -- если это раскомметировать поведение меняется



Код: sql
1.
2.
3.
4.
5.
6.
select
  REPLACE(T1.V, ' ', '0') AS V1,
  T1.X AS X1,
  REPLACE(T2.V, ' ', '0') AS V2,
  T2.X AS X2
from T T1 join T T2 on T1.V = T2.V



для fb3
Код: plaintext
1.
2.
3.
4.
PLAN HASH (T2 NATURAL, T1 NATURAL)

V1	X1	V2	X2
ww	1	ww	1
ww0	2	ww0	2

для fb 2.5.5
Код: plaintext
1.
2.
3.
4.
PLAN MERGE (SORT (T2 NATURAL), SORT (T1 NATURAL))

V1	X1	V2	X2
ww	1	ww	1
ww0	2	ww0	2

OK. Заменяем на LEFT JOIN. Здесь пока оптимизатор умеет воспользоваться только NESTED LOOP

Код: sql
1.
2.
3.
4.
5.
6.
select
  REPLACE(T1.V, ' ', '0') AS V1,
  T1.X AS X1,
  REPLACE(T2.V, ' ', '0') AS V2,
  T2.X AS X2
from T T1 left join T T2 on T1.V = T2.V



для fb3 и fb 2.5.5
Код: plaintext
1.
2.
3.
4.
5.
6.
PLAN JOIN (T1 NATURAL, T2 NATURAL)

V1	X1	V2	X2
ww	1	ww	1
ww	1	ww0	2
ww0	2	ww	1
ww0	2	ww0	2

Если раскоментировать создание индекса, то результат будет такой же как для LEFT JOIN, ну за исключением плана.

В трекер пойдёшь?
...
Рейтинг: 0 / 0
баг?
    #39026853
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
fb userПонял, оказывается collation в CREATE DATABASE - это не collation для базы, а дефолтный collation для чарсета.
Поэтому меняется так:
Код: sql
1.
alter character set WIN1251 set default collation WIN1251_NOPAD


И всё работает, только IBExpert перестаёт открывать в этой базе таблицы, любые (даже с одним INT полем), молча, и перезапуск не помогает.
...
Рейтинг: 0 / 0
баг?
    #39026855
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
fb userfb userПонял, оказывается collation в CREATE DATABASE - это не collation для базы, а дефолтный collation для чарсета.
Поэтому меняется так:
Код: sql
1.
alter character set WIN1251 set default collation WIN1251_NOPAD


И всё работает, только IBExpert перестаёт открывать в этой базе таблицы, любые (даже с одним INT полем), молча, и перезапуск не помогает.
А вот если вернуть обратно, то после переконнекта таблицы открываются:
Код: sql
1.
alter character set WIN1251 set default collation WIN1251
...
Рейтинг: 0 / 0
баг?
    #39026869
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов ДенисВ трекер пойдёшь?
Нет пока.
...
Рейтинг: 0 / 0
баг?
    #39026876
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

в каком смысле работает и в каком перестаёт открывать таблицы. Ты имеешь ввиду что запросы работают, а таблицы (как объекты метаданных) на закладке данные ничего не показывает?

Есть смысл проверить в isql. Если там всё пашет, то это бага IBE
...
Рейтинг: 0 / 0
баг?
    #39027506
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денисв каком смысле работает и в каком перестаёт открывать таблицы.
Не открывает по даблклику на таблице. Ошибка в IBExpert.
...
Рейтинг: 0 / 0
баг?
    #39030275
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисfb userпропущено...

На снапшоте тройки. На 2.5 всё хорошо.

вообще-то у меня на 2.5.5 тоже воспроизводится. Это бага в методах соединения HASH/MERGE JOIN. Ибо стоит создать индекс и поведение меняется с точностью до наоборот. Или заменить JOIN на LEFT JOIN.

твой эксперимент

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
RECREATE TABLE T (
    V  VARCHAR(10),
    X  INTEGER
);

INSERT INTO T (V, X) VALUES ('ww', 1);
INSERT INTO T (V, X) VALUES ('ww ', 2);

COMMIT;

--CREATE INDEX IDX_T_V ON T(V); -- если это раскомметировать поведение меняется



Код: sql
1.
2.
3.
4.
5.
6.
select
  REPLACE(T1.V, ' ', '0') AS V1,
  T1.X AS X1,
  REPLACE(T2.V, ' ', '0') AS V2,
  T2.X AS X2
from T T1 join T T2 on T1.V = T2.V



для fb3
Код: plaintext
1.
2.
3.
4.
PLAN HASH (T2 NATURAL, T1 NATURAL)

V1	X1	V2	X2
ww	1	ww	1
ww0	2	ww0	2

для fb 2.5.5
Код: plaintext
1.
2.
3.
4.
PLAN MERGE (SORT (T2 NATURAL), SORT (T1 NATURAL))

V1	X1	V2	X2
ww	1	ww	1
ww0	2	ww0	2

OK. Заменяем на LEFT JOIN. Здесь пока оптимизатор умеет воспользоваться только NESTED LOOP

Код: sql
1.
2.
3.
4.
5.
6.
select
  REPLACE(T1.V, ' ', '0') AS V1,
  T1.X AS X1,
  REPLACE(T2.V, ' ', '0') AS V2,
  T2.X AS X2
from T T1 left join T T2 on T1.V = T2.V



для fb3 и fb 2.5.5
Код: plaintext
1.
2.
3.
4.
5.
6.
PLAN JOIN (T1 NATURAL, T2 NATURAL)

V1	X1	V2	X2
ww	1	ww	1
ww	1	ww0	2
ww0	2	ww	1
ww0	2	ww0	2

Если раскоментировать создание индекса, то результат будет такой же как для LEFT JOIN, ну за исключением плана.

В трекер пойдёшь?

dimitr,
это бага? Если да то известна ли она?
...
Рейтинг: 0 / 0
баг?
    #39030286
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

бага, заносите в трекер
...
Рейтинг: 0 / 0
баг?
    #39030289
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr,

CORE-4909
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / баг?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]