clsql: Почему таблицы добавляются «волшебным образом»? - PullRequest
2 голосов
/ 05 октября 2019

Предположим, у меня есть следующие две таблицы

(clsql:def-view-class class-a ()
  ((field-one :type integer
              :db-kind :key
              :db-constraints :auto-increment)
   (field-two :type string
              :initarg :two
              :db-constraints :not-null)))

(clsql:def-view-class class-b ()
  ((b-one :type integer
          :initarg :b-one
          :db-kind :key)))

(clsql:create-view-from-class 'class-a)
(clsql:create-view-from-class 'class-b)

Теперь я хочу записи класса-a, у которых нет соответствующей записи в классе-b. («Соответствующий» означает, что class-a.field-one отображается на class-bb-one.) Предположим, что в классе a есть следующие две записи:

(clsql:update-records-from-instance (make-instance 'class-a :two "hello"))
(clsql:update-records-from-instance (make-instance 'class-a :two "world"))

Итак, запрос на выдачу будетbe:

(clsql:select 'class-a :from [class-a] ; class-b is added "magically"
              :where [not [in [class-a field-one]
                              [select [class-b b-one] :from [class-b]
                                      :where [= [class-a field-one]
                                                [class-b b-one]]]]])

Однако это также добавляет класс-b. (С целенаправленной ошибкой я получаю запрос, выполненный как:)

SELECT CLASS_A.FIELD_ONE,CLASS_A.FIELD_TWO FROM CLASS_A,CLASS_B 
  WHERE (NOT ((CLASS_A.FIELD_ONE 
                IN (SELECT CLASS_B.B_ONE FROM CLASS_B 
                      WHERE (CLASS_A.FIELD_ONE = CLASS_B.B_ONE)))))

С другой стороны,

(clsql:select [*] :from [class-a] ; see the [*]
              :where [not [in [class-a field-one]
                              [select [class-b b-one] :from [class-b]
                                      :where [= [class-a field-one]
                                                [class-b b-one]]]]])

переводится в ожидаемый:

SELECT * FROM CLASS_A 
  WHERE (NOT ((CLASS_A.FIELD_ONE 
                IN (SELECT CLASS_B.B_ONE FROM CLASS_B 
                      WHERE (CLASS_A.FIELD_ONE = CLASS_B.B_ONE)))))

Это ошибка или есть какая-то причина этого перевода?

1 Ответ

1 голос
/ 05 октября 2019

Начиная с версии 6.7.0, переопределение функции clsql-sys::%tables-for-query делает ее работающей "как положено", не нарушая ничего в веб-приложении, над которым я работаю:

(in-package :clsql-sys)

(defun %tables-for-query (classes from where inner-joins)
  (declare (ignore where inner-joins))
  (union (mapcar #'select-table-sql-expr classes)
         (listify from)))

Но я не запускалтестовые случаи clsql-tests.

...