已更新。 我在MySQL中创建了一个测试表。
CREATE TABLE sizes (
size ENUM('small', 'medium', 'large')
;
insert into sizes values ('small'),('medium'),('medium');
在Postgresql中,
CREATE FOREIGN TABLE sizes("size" text) SERVER test_server OPTIONS (dbname 'enumtest', table_name 'sizes');
然后可以正确执行select * from sizes;
。
我的问题是
我可以在PostgreSQL中定义多种数据类型吗?
DO $$BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type WHERE typname = 'size_t')
THEN CREATE TYPE size_t AS enum('small','medium','large');
END IF;
END$$;
不是像测试一样使用ENUM进行测试?我尝试替换不起作用。
DO $$BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type WHERE typname = 'size_t')
THEN CREATE TYPE size_t AS text;
END IF;
END$$;
或者有什么办法可以使我可以使用IMPORT FOREIGN SCHEMA
?
非常感谢你!
原件: 问题是当我刷新实例化视图或使用数据创建实例化视图时。我遇到这种错误。
ERROR: XX000: cache lookup failed for type 0
LOCATION: format_type_extended, format_type.c:128
我正在刷新实例化视图,该视图从mysql_fdw导入的外部表中进行选择。 MySQL数据库中的表具有enum
类型的列。在导入外部表之前,我做了PostgreSQL注意到的数据类型设置。
MySQL表中的数据类型为
brandCategory enum('S1','S2','S3','T','(N/A)')
在PostgreSQL中创建数据类型的代码是
DO $$BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type
WHERE typname = 'brandcategory_t')
THEN
CREATE TYPE brandcategory_t
AS enum('S1','S2','S3','T','(N/A)');
END IF;
END$$;
然后导入外部表。
IMPORT FOREIGN SCHEMA admin_testdb FROM SERVER mysql_server INTO public;
更改外部表的名称并创建实例化视图。
ALTER TABLE"tbl_Brand" RENAME TO "tbl_Brand_v";
CREATE MATERIALIZED VIEW "tbl_Brand" AS SELECT * FROM "tbl_Brand_v" WITH DATA;
\d "tbl_Brand_v"
的结果是
Foreign table "public.tbl_Brand_v"
Column | Type | Collation | Nullable | Default | FDW options
---------------+-----------------------------+-----------+----------+---------+-------------
brandId | integer | | not null | |
brandCode | character varying(30) | | | |
brandName | character varying(200) | | | |
brandCategory | brandcategory_t | | | |
brandRemark | text | | | |
brandActive | smallint | | | |
dtCreated | timestamp without time zone | | | |
personCreated | integer | | | |
dtUpdated | timestamp without time zone | | | |
personUpdated | integer | | | |
dtDeleted | timestamp without time zone | | | |
personDeleted | integer | | | |
\dT+ brandcategory_t
的结果是
List of data types
Schema | Name | Internal name | Size | Elements | Owner | Access privileges | Description
--------+-----------------+-----------------+------+----------+----------+-------------------+-------------
public | brandcategory_t | brandcategory_t | 4 | S1 +| postgres | |
| | | | S2 +| | |
| | | | S3 +| | |
| | | | T +| | |
| | | | (N/A) | | |
这是执行select * from "tbl_Brand_v";
时的堆栈跟踪。
#0 errfinish (dummy=dummy@entry=0) at elog.c:414
#1 0x0000000000851fa8 in elog_finish (elevel=elevel@entry=20, fmt=fmt@entry=0x8963a0 "cache lookup failed for type
%u") at elog.c:1376
#2 0x0000000000788acd in format_type_extended (type_oid=type_oid@entry=0, typemod=typemod@entry=-1, flags=flags@en
try=0) at format_type.c:151
#3 0x0000000000788b4c in format_type_be (type_oid=type_oid@entry=0) at format_type.c:330
#4 0x000000000077f289 in enum_in (fcinfo=<optimized out>) at enum.c:46
#5 0x0000000000855747 in OidFunctionCall3Coll (functionId=functionId@entry=3506, collation=collation@entry=0, arg1
=40290088, arg2=arg2@entry=0, arg3=arg3@entry=18446744073709551615) at fmgr.c:1471
#6 0x00007ff6e0eab16c in mysql_convert_to_pg (pgtyp=<optimized out>, pgtypmod=<optimized out>, column=<optimized o
ut>) at mysql_query.c:160
#7 0x00007ff6e0ead52c in mysqlIterateForeignScan (node=<optimized out>) at mysql_fdw.c:652
#8 0x000000000062eccb in ForeignNext (node=node@entry=0x254b8c0) at nodeForeignscan.c:54
#9 0x000000000060c9fa in ExecScanFetch (recheckMtd=0x62eb80 <ForeignRecheck>, accessMtd=0x62ec30 <ForeignNext>, no
de=0x254b8c0) at execScan.c:95
#10 ExecScan (node=0x254b8c0, accessMtd=0x62ec30 <ForeignNext>, recheckMtd=0x62eb80 <ForeignRecheck>) at execScan.c
:145
#11 0x000000000060468a in ExecProcNode (node=0x254b8c0) at ../../../src/include/executor/executor.h:247
#12 ExecutePlan (execute_once=<optimized out>, dest=0x25fe9f0, direction=<optimized out>, numberTuples=0, sendTuple
s=true, operation=CMD_SELECT, use_parallel_mode=<optimized out>, planstate=0x254b8c0, estate=0x254b6b0) at execMain
.c:1723
#13 standard_ExecutorRun (queryDesc=0x2549430, direction=<optimized out>, count=0, execute_once=<optimized out>) at
execMain.c:364
#14 0x0000000000746f1b in PortalRunSelect (portal=portal@entry=0x258d250, forward=forward@entry=true, count=0, coun
t@entry=9223372036854775807, dest=dest@entry=0x25fe9f0) at pquery.c:932
#15 0x00000000007482df in PortalRun (portal=<optimized out>, count=9223372036854775807, isTopLevel=<optimized out>,
run_once=<optimized out>, dest=0x25fe9f0, altdest=0x25fe9f0, completionTag=0x7ffdbb422200 "") at pquery.c:773
#16 0x0000000000744287 in exec_simple_query (query_string=<optimized out>) at postgres.c:1145
#17 0x0000000000745552 in PostgresMain (argc=<optimized out>, argv=<optimized out>, dbname=<optimized out>, usernam
e=<optimized out>) at postgres.c:4182
#18 0x0000000000480571 in BackendRun (port=0x2549730) at postmaster.c:4358
#19 BackendStartup (port=0x2549730) at postmaster.c:4030
#20 ServerLoop () at postmaster.c:1707
#21 0x00000000006d8639 in PostmasterMain (argc=argc@entry=3, argv=argv@entry=0x2521280) at postmaster.c:1380
#22 0x00000000004813cf in main (argc=3, argv=0x2521280) at main.c:228
我希望可以通过数据刷新或创建实例化视图,但会出现错误。
答案 0 :(得分:0)
有两个问题共同产生这种效果:
错误的枚举数据值。
枚举类型输入函数enum_in
尝试将它从MySQL接收的字符串转换为brandcategory_t
。
在159行中,此函数检查
if (strlen(name) >= NAMEDATALEN)
其中name
是从MySQL接收的值。
因此,MySQL表中必须有一行包含该枚举值的超过63个字节的字符串。
(假设mysql_fdw的代码是正确的,并且按照它说的做。)
mysql_fdw中的错误:
mysql_query.c
中的第160行显示:
value_datum = OidFunctionCall3(typeinput, valueDatum, ObjectIdGetDatum(InvalidOid), Int32GetDatum(typemod));
调用的类型输入函数为enum_in
,如果该函数遇到错误,它将尝试在错误消息中包括枚举类型的名称。
枚举类型是OidFunctionCall3
调用的第三个参数,因此它是ObjectIdGetDatum(InvalidOid)
。
InvalidOid
为0,enum_in
可以抛出您看到的错误。
您应将此错误报告给mysql_fdw。