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

Не работает регистрация составного ключа #183

Open
Lispython opened this issue Nov 9, 2018 · 4 comments

Comments

@Lispython
Copy link

Тестирую возможность расширения для секционирования таблиц.

Создал таблицу следующей структуры:

                                            Table "public.message"
        Column         |           Type           | Collation | Nullable |                     Default
-----------------------+--------------------------+-----------+----------+-------------------------------------------------
 id                    | integer                  |           | not null | nextval('message_id_seq'::regclass)
 created_at            | timestamp with time zone |           | not null | now()
 status                | integer                  |           |          |
 transaction_id        | character varying(124)   |           | not null |

Indexes:
    "message_pkey" PRIMARY KEY, btree (id)
    "message_transaction_id__pkey" UNIQUE CONSTRAINT, btree (transaction_id)
    "message_created_at__idx" btree (created_at)

Хочу секционировать таблицу по месяцам с использованием составного ключа по документации https://postgrespro.ru/docs/postgrespro/10/pg-pathman#PG-PATHMAN-INTERNALS:

  1. Создаю свой тип CREATE TYPE partition_key_year_and_month AS (year float8, month float8);
  2. SELECT create_naming_sequence('message');
  3. На выполнение запроса SELECT add_to_pathman_config('message', '(extract(year from created_at), extract(month from created_at))::partition_key_year_and_month', NULL); вылетает следующая ошибка:
ERROR:  failed to analyze partitioning expression "(extract(year from created_at), extract(month from created_at))::partition_key_year_and_month"
DETAIL:  functions in partitioning expression must be marked IMMUTABLE

Environment

  extname   | extowner | extnamespace | extrelocatable | extversion |   extconfig   | extcondition
------------+----------+--------------+----------------+------------+---------------+--------------
 plpgsql    |       10 |           11 | f              | 1.0        |               |
 pg_pathman |       10 |         2200 | f              | 1.5        | {16387,16398} | {"",""}
                                                             version
----------------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 11.0 (Debian 11.0-1.pgdg90+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit
(1 row)
ERROR:  function get_pathman_lib_version() does not exist
LINE 1: SELECT get_pathman_lib_version();
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
@ildus
Copy link
Collaborator

ildus commented Nov 15, 2018

Пробовали сделать отдельную функцию которая возвращает этот тип из какой либо даты, и отметить функцию как IMMUTABLE?

@xo4yecTb
Copy link

xo4yecTb commented Sep 30, 2019

Добрый день, тот же самый вопрос, только свои функции я создал и отметил их как IMMUTABLE:

CREATE FUNCTION extract_month(timestamp) RETURNS double precision
AS $BODY$ select extract(month from $1) $BODY$ 
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

CREATE FUNCTION extract_year(timestamp) RETURNS double precision
AS $BODY$ select extract(year from $1) $BODY$ 
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

затем

select add_to_pathman_config('table','(extract_year(created_at::timestamp),extract_month(created_at::timestamp))::outcomes_key',NULL);
ОШИБКА:  failed to analyze partitioning expression "(extract_year(created_at::timestamp),extract_month(created_at::timestamp))::outcomes_key"
ПОДРОБНОСТИ:  functions in partitioning expression must be marked IMMUTABLE

Что здесь не так? @ildus

@knizhnik
Copy link

knizhnik commented Oct 1, 2019

Проблема на в пасмане и не в extract, а в with time zone.
Если вы попробуете создать функциональный индекс, то получите такую же ошибку:

create table tt(t timestamp with time zone);
create index tti on tt (extract(year from t));
ERROR: functions in index expression must be marked IMMUTABLE

Если же вы не используете with time zone, то всё будет нормально:

create table tt(t timestamp);
create index tti on tt (extract(year from t));

В вашем случае объявление immutable функций не решало проблему, потому как параметр функции был объявлен как timestamp и поэтому всё равно происходило преробразование timestamp with timezone в timestamp, которое не immutable.

Проблему можно решить объявив параметр функиии как timestamp with timezone:

CREATE FUNCTION extract_month(timestamp with time zone) RETURNS double precision
AS $BODY$ select extract(month from $1) $BODY$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

create table tt(t timestamp with time zone);
create index tti on tt (extract_month(t));
CREATE INDEX

@xo4yecTb
Copy link

xo4yecTb commented Oct 1, 2019

@knizhnik благодарю за помощь!

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

No branches or pull requests

4 participants