Сбой дампа и восстановления базы данных PostgreSQL с сопоставлением hstore
у меня есть представление, которое сравнивает два hstore
столбцы.
когда я дамп и восстановить эту базу данных, восстановление завершается со следующим сообщением об ошибке:
Importing /tmp/hstore_test_2014-05-12.backup...
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 172; 1259 1358132 VIEW hstore_test_view xxxx
pg_restore: [archiver (db)] could not execute query: ERROR: operator does not exist: public.hstore = public.hstore
LINE 2: SELECT NULLIF(hstore_test_table.column1, hstore_test_table....
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Command was: CREATE VIEW hstore_test_view AS
SELECT NULLIF(hstore_test_table.column1, hstore_test_table.column2) AS "nullif"
FROM hst...
pg_restore: [archiver (db)] could not execute query: ERROR: relation "hstore_test_schema.hstore_test_view" does not exist
Command was: ALTER TABLE hstore_test_schema.hstore_test_view OWNER TO xxxx;
я смог создать эту ошибку в PostgreSQL 9.3.0 со следующими шагами:
CREATE DATABASE hstore_test;
c hstore_test
CREATE EXTENSION hstore WITH SCHEMA public;
CREATE SCHEMA hstore_test_schema;
CREATE TABLE hstore_test_schema.hstore_test_table(
id int,
column1 hstore,
column2 hstore,
PRIMARY KEY( id )
);
CREATE VIEW hstore_test_schema.hstore_test_view AS
SELECT NULLIF(column1, column2) AS comparison FROM hstore_test_schema.hstore_test_table;
для полноты, дамп и процесс восстановления выглядел так:
pg_dump -U xxxx -h localhost -f /tmp/hstore_test_2014-05-12.backup -Fc hstore_test
psql -U xxxx -h localhost -d postgres -c "DROP DATABASE hstore_test"
psql -U xxxx -h localhost -d postgres -c "CREATE DATABASE hstore_test"
pg_restore -U xxxx -h localhost -d hstore_test /tmp/hstore_test_2014-05-12.backup
pg_restore -l /tmp/hstore_test_2014-05-12.backup
говорит о том, что hstore
расширение включено до представления создано:
;
; Archive created at Mon May 12 11:18:32 2014
; dbname: hstore_test
; TOC Entries: 15
; Compression: -1
; Dump Version: 1.12-0
; Format: CUSTOM
; Integer: 4 bytes
; Offset: 8 bytes
; Dumped from database version: 9.3.0
; Dumped by pg_dump version: 9.3.0
;
;
; Selected TOC Entries:
;
2074; 1262 1358002 DATABASE - hstore_test xxxx
7; 2615 1358003 SCHEMA - hstore_test_schema xxxx
5; 2615 2200 SCHEMA - public postgres
2075; 0 0 COMMENT - SCHEMA public postgres
2076; 0 0 ACL - public postgres
173; 3079 11787 EXTENSION - plpgsql
2077; 0 0 COMMENT - EXTENSION plpgsql
174; 3079 1358004 EXTENSION - hstore
2078; 0 0 COMMENT - EXTENSION hstore
171; 1259 1358124 TABLE hstore_test_schema hstore_test_table xxxx
172; 1259 1358132 VIEW hstore_test_schema hstore_test_view xxxx
2069; 0 1358124 TABLE DATA hstore_test_schema hstore_test_table xxxx
1960; 2606 1358131 CONSTRAINT hstore_test_schema hstore_test_table_pkey xxxx
кстати, заменив NULLIF(col1, col2)
С col1 = col2
кажется, что ошибка исчезает, несмотря на то, что это явное сравнение типа pg_restore
жаловался.
1 ответов
это ошибка PostgreSQL. я передал ваш отчет в pgsql-список ошибок.
то, что происходит, это pg_dump
параметр search_path
исключить public
при создании таблиц в схеме. Это нормально. Когда он сбрасывает объекты, которые относятся к вещам, которые не находятся на search_path
, это явно схема-квалифицирует их, чтобы они работали.
он работает в =
случае, потому что pg_dump
видит, что =
на самом деле OPERATOR(public.=)
в этом дело, и сбрасывает его в таком виде:
CREATE VIEW hstore_test_view AS
SELECT (hstore_test_table.column1 OPERATOR(public.=) hstore_test_table.column2) AS comparison
FROM hstore_test_table;
, pg_dump
не удается сделать это для оператора неявно используется через nullif
псевдо-функции. Это приводит к следующей фиктивной последовательности команд:
CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;
...
SET search_path = hstore_test_schema, pg_catalog;
...
CREATE VIEW hstore_test_view AS
SELECT NULLIF(hstore_test_table.column1, hstore_test_table.column2) AS comparison
FROM hstore_test_table;
pg_dump
просто использует 0', location=location@entry=58) at parse_oper.c:440
#2 0x000000000051ad34 in make_op (pstate=pstate@entry=0x1189f38, opname=0x1189c10, ltree=ltree@entry=0x118a528, rtree=0x118a590, location=58) at parse_oper.c:770
#3 0x00000000005155e1 in transformAExprNullIf (a=0x1189bc0, pstate=0x1189f38) at parse_expr.c:1021
#4 transformExprRecurse (pstate=pstate@entry=0x1189f38, expr=0x1189bc0) at parse_expr.c:244
#5 0x0000000000517484 in transformExpr (pstate=0x1189f38, expr=<optimized out>, exprKind=exprKind@entry=EXPR_KIND_SELECT_TARGET) at parse_expr.c:116
#6 0x000000000051ff30 in transformTargetEntry (pstate=pstate@entry=0x1189f38, node=0x1189bc0, expr=expr@entry=0x0, exprKind=exprKind@entry=EXPR_KIND_SELECT_TARGET,
colname=0x1189ba0 "comparison", resjunk=resjunk@entry=0 '0') at parse_target.c:94
#7 0x00000000005212df in transformTargetList (pstate=pstate@entry=0x1189f38, targetlist=<optimized out>, exprKind=exprKind@entry=EXPR_KIND_SELECT_TARGET)
at parse_target.c:167
#8 0x00000000004ef594 in transformSelectStmt (stmt=0x11899f0, pstate=0x1189f38) at analyze.c:942
#9 transformStmt (pstate=0x1189f38, parseTree=0x11899f0) at analyze.c:243
#10 0x00000000004f0a2d in parse_analyze (parseTree=0x11899f0,
sourceText=sourceText@entry=0x114e6b0 "CREATE VIEW hstore_test_schema.hstore_test_view AS\nSELECT NULLIF(column1, column2) AS comparison FROM hstore_test_schema.hstore_test_table;", paramTypes=paramTypes@entry=0x0, numParams=numParams@entry=0) at analyze.c:100
#11 0x000000000057cc4e in DefineView (stmt=stmt@entry=0x114f7e8,
queryString=queryString@entry=0x114e6b0 "CREATE VIEW hstore_test_schema.hstore_test_view AS\nSELECT NULLIF(column1, column2) AS comparison FROM hstore_test_schema.hstore_test_table;") at view.c:385
#12 0x000000000065b1cf in ProcessUtilitySlow (parsetree=parsetree@entry=0x114f7e8,
queryString=0x114e6b0 "CREATE VIEW hstore_test_schema.hstore_test_view AS\nSELECT NULLIF(column1, column2) AS comparison FROM hstore_test_schema.hstore_test_table;",
context=<optimized out>, params=params@entry=0x0, completionTag=completionTag@entry=0x7fffc98c9990 "", dest=<optimized out>) at utility.c:1207
#13 0x000000000065a54e in standard_ProcessUtility (parsetree=0x114f7e8, queryString=<optimized out>, context=<optimized out>, params=0x0, dest=<optimized out>,
completionTag=0x7fffc98c9990 "") at utility.c:829
таким образом, непосредственная проблема выглядит как transformAExprNullIf
не смотри вверх по оператору, используя тип его операнда через B-tree opclass и typecache.