2

更新。我在 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

我希望物化视图可以用数据刷新或创建,但出现错误。

4

1 回答 1

1

有两个问题结合起来产生这种效果:

  1. 错误的枚举数据值。

    枚举类型输入函数enum_in尝试将它从 MySQL 接收到的字符串转换为brandcategory_t.

    在第 159 行,此函数检查

    if (strlen(name) >= NAMEDATALEN)
    

    name从 MySQL 收到的值在哪里。

    所以 MySQL 表中必须有一行包含这个枚举值超过 63 个字节的字符串。

    (假设 mysql_fdw 的代码是正确的并且按照它所说的去做。)

  2. mysql_fdw 中的一个错误:

    第 160 行mysql_query.c内容如下:

    value_datum = OidFunctionCall3(typeinput, valueDatum, ObjectIdGetDatum(InvalidOid), Int32GetDatum(typemod));
    
    • 调用的类型输入函数 is enum_in,如果该函数遇到错误,它会尝试在错误消息中包含枚举类型的名称。

    • 枚举类型是OidFunctionCall3调用的第三个参数,所以它是ObjectIdGetDatum(InvalidOid).

    • InvalidOid是 0,并且enum_in可以理解地抛出您看到的错误。

    您应该将此错误报告给 mysql_fdw。

于 2019-08-29T10:55:34.650 回答