Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

При парсинге и сборке запроса добавлять таблицы сразу после главной #2376

Open
gsbelarus opened this issue Jun 30, 2015 · 12 comments

Comments

@gsbelarus
Copy link
Member

Originally reported on Google Code with ID 2376

При сборке запроса парсером, связанные таблицы (добавленные парсером) добавлять не в
конец секции from, а сразу за главной (первой?).

Reported by gs1994 on 2011-03-22 12:43:22

@gsbelarus
Copy link
Member Author

Речь идет о нашем существующем парсере.

Как проверить:

1) Берем чистый эталон
2) Создаем тип данных ссылка
3) На таблице gd_contact добавляем поле-аттрибут созданного типа

открываем справочник контактов, смотрим запрос и убеждаемся, что в ФРОМ часть добавился
джоин на на таблицу справочник. Запоминаем сформированный алиас этой таблицы.

Теперь перекрываем метод GetFromClause для объекта типа компания и добавляем джоин
на таблицу (неважно на какую, можно опять-таки на gd_contact), связываем ее с таблицей
справочником через тот алиас, который мы запомнили.

Запускаем. Убеждаемся, что запрос получился рабочий.

Reported by gs1994 on 2011-03-22 16:15:30

  • Labels added: gdcBase

@gsbelarus
Copy link
Member Author

Reported by gs1994 on 2011-03-22 16:15:49

@gsbelarus
Copy link
Member Author

Reported by gs1994 on 2011-03-22 16:17:14

@gsbelarus
Copy link
Member Author

А всегда ли хорошо добавлять сразу за главной (первой?)
Допустим есть Б.О.  TgdcAcctBaseEntryRegister, его FromClause:
' FROM ac_record z JOIN ac_entry r ON z.id = r.recordkey ' +
'   LEFT JOIN gd_document doc ON z.documentkey = doc.id ' +
'   LEFT JOIN ac_account c ON r.accountkey = c.id ' +
'   LEFT JOIN gd_curr cur ON r.currkey = cur.id ';
я так понимаю, предлагается сразу после ac_record присоединять таблицы, не повлияет
ли это на план выполнения запроса (раньше при смешении JOIN и LEFT JOIN план мог меняться)?

Reported by Alexander.GoldenSoft on 2011-03-22 16:26:47

@gsbelarus
Copy link
Member Author

План от порядка джоинов в тексте запроса не зависит.

Сейчас невозможно через GetFromClause добавить таблицу, которая связана с таблицей
атрибутов, добавляемой парсером.

Reported by gs1994 on 2011-03-22 16:34:12

@gsbelarus
Copy link
Member Author

Вообще, тут не так просто. Связанные таблицы справочники для аттрибутов надо добавлять
после таблиц, зашитых в ядре, но перед таблицами добавляемыми в GetFromClause.

Или оставить как есть, но что тогда делать в ситуациях, когда надо добавить таблицу
завязанную на таблицу справочник?

Reported by gs1994 on 2011-03-22 16:44:26

@gsbelarus
Copy link
Member Author

Можно пример, что не получается и как нужно сделать, а то как то непонятно

Reported by Alexander.GoldenSoft on 2011-03-22 19:04:32

@gsbelarus
Copy link
Member Author

Пример условный:

1) есть товар. запрос для него формируется

   SELECT z.* FROM gd_good z

2) добавляем атрибут Производитель. Это будет ссылка
на справочник клиентов. Теперь запрос будет формироваться
такой:

   SELECT z.*, usr_manufacturer.name
   FROM
     gd_good z
     LEFT JOIN gd_contact usr_manufacturer
       ON usr_manufacturer.id = z.usr$manufacturerkey

3) теперь, нам хочется отобразить ФИО директора производителя
для каждого товара. Добавляем в GetFromClause:

   inherited ...
   GetFromClause = GetFromClause & _
     " LEFT JOIN gd_contact dir ON dir.id = usr_manufacturer.directorkey "

и получаем ошибку, так как парсер запроса сначала отпарсит
FROM часть и в список таблиц закинет две таблицы: gd_good, gd_contact (для директора)
и только потом, ниже них, добавит джоин на таблицу для поля аттрибута.

из-за чего будет ошибка.


Возможно у такой (достаточно типовой задачи) есть и другое, более простое решение.
Какое?


Reported by gs1994 on 2011-03-23 08:56:36

@gsbelarus
Copy link
Member Author

Перемещение джоинов таблиц атрибутов в начало секции Фром решает одну проблему, но порождает
другую. Теперь, работающий код можно обрушить простым снятием галочки в настройках
поля таблицы. Справочник не добавится в Фром и получим ошибку о неверном запросе.

Надо сделать так:

1) Вернуть код парсера в исходное состояние
2) Модифицировать парсер таким образом, чтобы перед добавлением ЛЕФТ ДЖОИНА на таблицу
справочник проверялось, а нет ли уже такого ЛЕФТ ДЖОИНА в запросе.
3) Если есть, то используем его и не добавляем ничего
4) Нет -- действуем по старому.

Т.е.: пусть у нас есть таблица А с полем арибутом ссыкой на Б. Сейчас парсер формирует
такой запрос:

SELECT 
  z.*, 
  usr_b.name 
FROM 
  a z 
  LEFT JOIN b usr_b 
    ON z.attrkey = usr_b.id

Пусть программист перекрывает GetFromClause следующим образом:

  inherited
  GetFromClause = GetFromClause & _ 
    " LEFT JOIN b my_b ON z.attrkey = my_b.id " &_
    " LEFT JOIN c my_c ON my_b.cattrkey = my_c.id "

Парсер, видя что ЛЕФТ ДЖОИН на таблицу Б уже есть берет его, а не
добавляет еще один ЛЕФТ ДЖОИН в запрос. 

Итоговый запрос будет выглядеть следующим образом:

SELECT 
  z.*, 
  my_b.name,
  my_c.name   /* эту строчку добавляет программист перекрывая GetSeletClause */
FROM 
  a z 
  LEFT JOIN b my_b 
    ON z.attrkey = my_b.id
  LEFT JOIN c my_c
    ON my_b.cattrkey = my_c.id

Reported by gs1994 on 2011-03-24 08:39:34

@gsbelarus
Copy link
Member Author

http://gsbelarus.com/gs/wiki/index.php/GdcBase.TgdcBase.GetFromClause

Reported by gs1994 on 2011-03-30 16:28:06

  • Status changed: Fixed

@gsbelarus
Copy link
Member Author

Пока откатили код к исходному состоянию. Надо сначала решить проблему совместимости
с существующим кодом.

Reported by gs1994 on 2011-04-12 16:22:13

  • Status changed: Accepted

@NikolayUkleyko
Copy link

Коллеги, если, на ваш взгляд данная тема уже неактуальна, пожалуйста, закройте ее.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants