Ссылка на столбец Postgres неоднозначна при указании имени таблицы - PullRequest
0 голосов
/ 30 июня 2018

Это умеренно сложный CTE, который обновляет несколько таблиц в зависимости от содержимого аргумента JSON. При выполнении этой функции, Postgres выдает ошибку column reference "explode" is ambiguous. Строка, на которую ссылается ошибка, фактически имеет имя таблицы, определяющее ссылку на столбец.

Я почти уверен, что прав, какая строка вызывает проблему, как будто я удаляю помеченную ниже строку, ошибка исчезает.

Я пытался выяснить это некоторое время, и понятия не имею.

CREATE OR REPLACE FUNCTION prd.update_composition (json, OUT result json) AS
$$
BEGIN
  -- Update and return the new composition
  WITH composition AS (
    UPDATE prd.composition SET (
      explode
    ) = (
      payload_composition.explode
    )
    FROM json_to_record($1) AS payload_composition (
      id      integer,
      explode boolean
    )
    WHERE id IS NOT NULL
    RETURNING *
  ), payload_component AS (
    SELECT
      composition.composition_id,
      component."productId" AS product_id,
      component.quantity,
      component.removed
    FROM json_to_recordset($1->'components') AS component (
      "productId" integer,
      quantity    numeric(10,3),
      removed     boolean
    )
    CROSS JOIN composition
  ), updated_component AS (
    UPDATE prd.component existing SET (
      product_id,
      quantity
    ) = (
      component.product_id,
      component.quantity
    )
    FROM (
      SELECT
        composition_id,
        product_id,
        quantity
      FROM payload_component
      WHERE removed IS NOT TRUE
    ) component
    WHERE existing.composition_id = component.composition_id
    RETURNING *
  ), deleted AS (
    DELETE FROM prd.component existing
    USING (
      SELECT
        composition_id,
        product_id
      FROM payload_component
      WHERE removed IS TRUE
    ) payload_deleted
    WHERE existing.composition_id = payload_deleted.composition_id
      AND existing.product_id = payload_deleted.product_id
  )
  SELECT json_strip_nulls(to_json(r)) INTO result
  FROM (
    SELECT
      composition.composition_id,
      composition.explode -- HERE IS THE OFFENDING LINE --
    FROM composition
  ) r;
END
$$
LANGUAGE 'plpgsql' SECURITY DEFINER;

Почему существует ambiguous column reference error с этим кодом?

1 Ответ

0 голосов
/ 30 июня 2018

Проблема связана с предложением RETURNING в composition CTE.

Используя * с RETURNING, он возвращает все столбцы из всех таблиц в from_list.

В возвращающем предложении должно быть указано, какие столбцы и из каких таблиц возвращать, особенно если в from_list.

есть несколько таблиц

В этом случае псевдоним должен использоваться в INSERT для ссылки на требуемый Колонки:

WITH composition AS (
    UPDATE prd.composition c SET ( -- See here
      explode
    ) = (
      payload_composition.explode
    )
    FROM json_to_record($1) AS payload_composition (
      id      integer,
      explode boolean
    )
    WHERE id IS NOT NULL
    RETURNING c.* -- and here
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...