Error input of anonymous composite types is not implemented

I have a table with an XML column. The XML can contain an optional link element. 1d177dee-1da4-4451-b175-396666afc370 I

In the expression link != '{}' the alias link refers to the table, not a single column (because of tblData AS link).

Postgres allows to refer to the complete row of a table by using the table name (or table alias). The error is telling you that you can’t compare a complete row with a single array value.

You need something like this:

select distinct cast(xpath('/Data/Link', xmldata) AS TEXT) as linkdata
from data 
where cast(xpath('/Data/Link', xmldata) AS TEXT) <> '{}';

Unfortunately it’s not possible to use a column alias in the where clause. If you want to avoid repeating the expression, use a derived table:

select distinct linkdata 
from (
  select cast(xpath('/Data/Link', xmldata) AS TEXT) as linkdata
  from data 
) t 
where linkdata <> '{}';

But as you are only expecting a single link anyway, the following might better:

select distinct linkdata 
from (
  select (xpath('/Data/Link', xmldata))[1] as linkdata
  from data 
) t 
where linkdata is not null;

xpath() returns an array, the expression (xpath(..))[1] gets the first element of that array, if there is no such element, it returns null. Maybe you event want xpath('/Data/Link/UUID/text()') to only get the actual UUID, rather than the complete XML node — but that’s not clear from the example you provided.

Hey guys, I am using this image to fiddle with GitLab CI/CD implementation. My .gitlab-ci.yml file looks like this:

test:
  image: python:3.7.5
  services:
    - name: mdillon/postgis:11
      alias: postgres
    - name: redis:latest
  script:
    - apt-get update
    - pip install -U pip setuptools
    - pip install -r requirements_dev.txt
    - pytest -x --strict
  variables:
    POSTGRES_DB: testdb
    POSTGRES_USER: xxx
    POSTGRES_PASSWORD: xxx
    PGPASSWORD: xxx
    REDIS_HOST: redis
    REDIS_PORT: 6379

However, once tests start running, I’m getting following error which only happens inside CI/CD pipeline with this image:

statement = 'SELECT users.password AS users_password, users.created_at AS users_created_at, users.updated_at AS users_updated_at, ...ND users.id = user_followers.follows_id AND user_followers.state = %(state_1)s ORDER BY user_followers.updated_at DESC'
parameters = {'param_1': 3, 'state_1': 'yes'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7f8a2dce4490>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.NotSupportedError: (psycopg2.errors.FeatureNotSupported) input of anonymous composite types is not implemented
E       LINE 3: ...r_followers.follows_id AND user_followers.state = 'yes' ORDE...
E                                                                    ^

Does anyone have an idea about whats going on? It seems to have problems with ENUM PostgreSQL types, but I am not sure on how to debug or fix this. I am not able to reproduce this error outside of the container.

В выражении link != ‘{}’ псевдоним link относится к Таблица, а не к отдельному столбцу (из-за tblData AS link).

Postgres позволяет ссылаться на всю строку таблицы, используя имя таблицы (или псевдоним таблицы). Ошибка сообщает вам, что вы не можете сравнить полную строку с одним значением массива.

Вам понадобится что-то вроде этого:

select distinct cast(xpath('/Data/Link', xmldata) AS TEXT) as linkdata
from data 
where cast(xpath('/Data/Link', xmldata) AS TEXT) <> '{}';

К сожалению, в предложении where невозможно использовать псевдоним столбца. Если вы хотите избежать повторения выражения, используйте производную таблицу:

select distinct linkdata 
from (
  select cast(xpath('/Data/Link', xmldata) AS TEXT) as linkdata
  from data 
) t 
where linkdata <> '{}';

Но поскольку вы в любом случае ожидаете только ссылку Один, лучше может быть следующее:

select distinct linkdata 
from (
  select (xpath('/Data/Link', xmldata))[1] as linkdata
  from data 
) t 
where linkdata is not null;

Xpath() возвращает массив, выражение (xpath(..))[1] получает первый элемент этого массива, если такого элемента нет, оно возвращает ноль. Возможно, вы хотите, чтобы xpath(‘/Data/Link/UUID/text()’) получал только фактический UUID, а не полный узел XML, но это не ясно из приведенного вами примера.

I have a table with an XML column. The XML can contain an optional link element.

<Link ReasonCode="MultiLabel">
  <UUID>1d177dee-1da4-4451-b175-396666afc370</UUID>
</Link>

I want to fetch all records from the table that do not have link element. From those records that have the link element, I want only the DISTINCT records fetched. If two records have the same link element, skip the second occurrence. The query that I tried,

SELECT DISTINCT cast((xpath('/Data/Link', xmldata)) AS TEXT) 
FROM tblData AS link 
WHERE link != '{}'

ERROR: input of anonymous composite types is not implemented

  1. What is it that I am doing wrong here that causes the above mentioned error? The query works fine without the WHERE clause.
  2. In addition to this I want to use an order by clause before the DISTINCT method starts processing the results. Again, I messed up with the syntax of using order by and distinct together, and I got an error.

How do I achieve ordering of the results based on the value of a column in the table, for this query?

Advertisement

Answer

In the expression link != '{}' the alias link refers to the table, not a single column (because of tblData AS link).

Postgres allows to refer to the complete row of a table by using the table name (or table alias). The error is telling you that you can’t compare a complete row with a single array value.

You need something like this:

select distinct cast(xpath('/Data/Link', xmldata) AS TEXT) as linkdata
from data 
where cast(xpath('/Data/Link', xmldata) AS TEXT) <> '{}';

Unfortunately it’s not possible to use a column alias in the where clause. If you want to avoid repeating the expression, use a derived table:

select distinct linkdata 
from (
  select cast(xpath('/Data/Link', xmldata) AS TEXT) as linkdata
  from data 
) t 
where linkdata <> '{}';

But as you are only expecting a single link anyway, the following might better:

select distinct linkdata 
from (
  select (xpath('/Data/Link', xmldata))[1] as linkdata
  from data 
) t 
where linkdata is not null;

xpath() returns an array, the expression (xpath(..))[1] gets the first element of that array, if there is no such element, it returns null. Maybe you event want xpath('/Data/Link/UUID/text()') to only get the actual UUID, rather than the complete XML node – but that’s not clear from the example you provided.

Would it be possible to know what is the meaning of this error "error: SQL error: input of anonymous composite types is not implemented"

I am getting the above error("error: SQL error: input of anonymous composite types is not implemented") when I perform the below query,

select *
from dev d
where not exists (select *
                  from ( 
                    select * 
                    from jsonb_array_elements_text(d.json_id -> 'sourcedepartmentId')
                    where jsonb_typeof(d.json_id -> 'sourcedepartmentId') = 'array'
                    and d.json_id -> 'sourcedepartmentId' is not null
                    union all
                    select d.json_id ->> 'sourcedepartmentId'
                    where jsonb_typeof(d.json_id -> 'sourcedepartmentId') = 'string'
                    and and d.json_id -> 'sourcedepartmentId' is not null
                  )  as jdata
                  where jdata in (....)
                 )

Any help would be much appreciated. Thanks. The above statment

I have a table with an XML column. The XML can contain an optional link element.

<Link ReasonCode="MultiLabel">
  <UUID>1d177dee-1da4-4451-b175-396666afc370</UUID>
</Link>

I want to fetch all records from the table that do not have link element. From those records that have the link element, I want only the DISTINCT records fetched. If two records have the same link element, skip the second occurrence. The query that I tried,

SELECT DISTINCT cast((xpath('/Data/Link', xmldata)) AS TEXT) 
FROM tblData AS link 
WHERE link != '{}'

ERROR: input of anonymous composite types is not implemented

  1. What is it that I am doing wrong here that causes the above mentioned error? The query works fine without the WHERE clause.
  2. In addition to this I want to use an order by clause before the DISTINCT method starts processing the results. Again, I messed up with the syntax of using order by and distinct together, and I got an error.

How do I achieve ordering of the results based on the value of a column in the table, for this query?

Andrew Kiellor <akiellor(at)gmail(dot)com> writes:
> Sorry I omitted the output. It is as follows:

> psql:test.sql:14: ERROR: input of anonymous composite types is not implemented
> LINE 1: SELECT * FROM table1 WHERE column1 = ‘(0)’;
> ^

I think this is operating as designed. I agree it’d be slightly more
convenient if the parser would infer that the RHS must be of the same
type as the LHS, but shoehorning that into the existing system design
seems problematic. The record_eq operator doesn’t actually require
that its inputs be of identical composite types, only compatible ones.
To continue your example:

regression=# CREATE TYPE type2 AS (xyz int);
CREATE TYPE
regression=# SELECT * FROM table1 WHERE column1 = ‘(0)’::type2;
column1
———
(0)
(1 row)

regression=# CREATE TYPE type3 AS (x float);
CREATE TYPE
regression=# SELECT * FROM table1 WHERE column1 = ‘(0)’::type3;
ERROR: cannot compare dissimilar column types integer and double precision at record column 1

So if the parser assumed that the inputs must be of the same composite
type, it’d be exceeding its authority, and would likely cause queries
that work today to start failing.

The back story here is that type «record» isn’t really a polymorphic
type, though it behaves similarly to those types in some ways. If we
were designing in a green field it’d make sense to treat «record»
according to the polymorphism rules. But we’re not; «record» is way
older than the polymorphics so it has various unique idiosyncrasies.
The one that’s relevant here is that an input argument that’s declared
to be «record» isn’t required to be the same composite type as another
argument also declared as «record».

regards, tom lane

Можно ли узнать, что означает эта ошибка «error: SQL error: input of anonymous composite types is not implemented»

Я получаю указанную выше ошибку («error: SQL error: input of anonymous composite types is not implemented»), когда выполняю приведенный ниже запрос,

select *
from dev d
where not exists (select *
                  from ( 
                    select * 
                    from jsonb_array_elements_text(d.json_id -> 'sourcedepartmentId')
                    where jsonb_typeof(d.json_id -> 'sourcedepartmentId') = 'array'
                    and d.json_id -> 'sourcedepartmentId' is not null
                    union all
                    select d.json_id ->> 'sourcedepartmentId'
                    where jsonb_typeof(d.json_id -> 'sourcedepartmentId') = 'string'
                    and d.json_id -> 'sourcedepartmentId' is not null
                  )  as jdata
                  where jdata in (  '109ec13a-46bd-26fe-6b1f-c4f329c76fda', 
                                    'fcf6f607-54f7-4e7c-8a42-23b66091a435', 
                                    '2dd35f81-27ce-55eb-bd3e-e46be3a378c4', 
                                    '1b381823-1df1-4ced-8b66-baad6e2456ee' )
                  )

D.json_id -> ‘sourcedepartmentId’ будет иметь значения, как показано ниже,

  • только с одним значением UUID. Пример: ["ba18e414-92d3-446b-91b4-67050f891121"] или
  • несколько значений uuid в виде массива. Пример: ["45b90b79-1151-4d8c-8785-4886607524bd", "70b9de47-5e10-42a5-bf30-81c0d4efe6bd", "e1f30960-06eb-41b4-9ca7-49b389defcab", "5cb85419-7fb7-45bd-ae8c-46b3d7ab9154"] или
  • нулевое или пустое значение.

Выдержка из схемы таблицы для таблицы с именем dev,

идентификатор разработчика Имя сотрудника JSON-идентификатор
ef7fd5df-7881-470d-bc7d-846211df0344 Том {«sourcedevIds»:[],»sourcedepartmentId»:[«45b90b79-3457-4d8c-8567-4886602367bd»]}
345р34-2345-56ыт-78уи-343тртрфг567 Джон {«sourcedevIds»:[«wedfrtg-3456-3trr-6887-rte45R3″],»sourcedepartmentId»:[«45b90b79-1050-4d8c-8785-4886607524bd», «70b9de23-5e12-42a5-bf30-81c0d4efe6bd», «501f300 -06eb-41b4-9ca7-49b456defcab», «5cb84516-7fb7-23bd-ae8c-46b3d7ab3467»]}

|345r34-2345-56yt-78ui-343trtrfg567 | Брайан | {«sourcedevIds»:[«wedfrtg-7890-3trr-6887-rte45R3″],»sourcedepartmentId»:[]}|

Любая помощь приветствуется. Спасибо.


JSONB, 20 марта 2022 г., 15:55

55

1


Ответ:

Решено

«jdata» — это псевдоним таблицы, а не псевдоним столбца. Вы должны назначить псевдоним столбца, а затем использовать его. Использование псевдонима таблицы, как если бы это было имя столбца, возможно, но здесь это не то, что вам нужно, и рассматривается как составной тип.

...) as jdata(col1)
where col1 in (...

Конечно, было бы лучше назначить осмысленный псевдоним, а не просто «col1».


jjanes, 20 марта 2022 г., 19:22

Интересные вопросы для изучения

Понравилась статья? Поделить с друзьями:
  • Error input file does not exist
  • Error input angular
  • Error innodb unable to lock ibdata1 error 11
  • Error innodb plugin initialization aborted with error generic error
  • Error innodb operating system error number 2 in a file operation