MACADDR /的Inet类型的Postgres该油滑(Macaddr/Inet type of

2019-09-27 10:29发布

我的应用程序使用光滑(V2.0.0)来管理一个PostgreSQL(9.1)数据库。

我的一个表中包含网络设备,因此Mac和IP的地址。 我用的Postgres类型macaddrinet ,因为他们似乎是任务的理想工具。 现在我想用滑溜溜的解除emebedding但很难定义我的表。 当我自动生成的代码为我的表,我注意到String来代替那些类型,但并不介意。

这工作正常从数据库读取,但是当我尝试更新或插入一行它会导致

org.postgresql.util.PSQLException: ERROR: 
column "mac" is of type macaddr but expression is of type character varying
Hint: You will need to rewrite or cast the expression.

至极似乎很合乎逻辑。

现在的问题是我怎么能告诉滑头说:

  • 这collumn实际上是一个类型的macaddr / inet

要么

  • 这collumn需要插入之前铸造,但可以以其他方式被视为一个字符串

更新:

克雷格说明我已经创建了周围使用包装函数隐式转换macaddr_ininet_in

\dC macaddr
                 List of casts
 Source type | Target type |    Function    | Implicit?
-------------+-------------+----------------+-----------
 text        | macaddr     | macaddr_intext | yes

\dC inet
                        List of casts
 Source type |    Target type    |      Function      |   Implicit?
-------------+-------------------+--------------------+---------------
 cidr        | inet              | (binary coercible) | yes
 inet        | character         | text               | in assignment
 inet        | character varying | text               | in assignment
 inet        | cidr              | cidr               | in assignment
 inet        | text              | text               | in assignment
 text        | inet              | inet_intext        | yes

\df+ macaddr_intext
                                                                  List of functions
 Schema |      Name      | Result data type | Argument data types |  Type  | Volatility |  Owner   | Language |           Source code           | Description
--------+----------------+------------------+---------------------+--------+------------+----------+----------+---------------------------------+-------------
 public | macaddr_intext | macaddr          | text                | normal | immutable  | postgres | sql      |                                 |
                                                                                                              : select macaddr_in($1::cstring);
                                                                                                              :

\df+ inet_intext
                                                               List of functions
 Schema |    Name     | Result data type | Argument data types |  Type  | Volatility |  Owner   | Language |         Source code          | Description
--------+-------------+------------------+---------------------+--------+------------+----------+----------+------------------------------+-------------
 public | inet_intext | inet             | text                | normal | immutable  | postgres | sql      |                              |
                                                                                                           : select inet_in($1::cstring);
                                                                                                           :

ERRORMESSAGE仍然是完全一样的,如上所示。

Commads重现:

psql <tablename>

create or replace function macaddr_intext(text) returns macaddr as $$
select macaddr_in($1::cstring);
$$ language sql immutable;

create cast (text as macaddr) with function macaddr_intext(text) as implicit;

create or replace function inet_intext(text) returns inet as $$
select inet_in($1::cstring);
$$ language sql immutable;

create cast (text as inet) with function inet_intext(text) as implicit;

UPDATE2:

我把范围缩小到一个权限错误,因为如果我作为用户身份运行postgres

mydb=# create table test(i inet, m macaddr)
CREATE TABLE
mydb=# insert into test values ('1.1.1.1'::text, '00:00:00:00:00:00'::text);
INSERT 0 1

但如果我尝试运行它实际上试图插入用户

mydb=> insert into test values ('1.1.1.1'::text, '00:00:00:00:00:00'::text);
ERROR: permission denied for relation test

建立数据库时我已经运行:

template1=# GRANT ALL PRIVILEGES ON DATABASE mydb to myuser;

UPDATE3:

UPDATE2横空出世,因为所创建的表是由拥有的只是问题postgres ,而不是myuser

Answer 1:

这是问题很多人都用的变体jsonXML ,并归结为一个事实,即PostgreSQL是太严格有关数据类型之间的转换。

见这个答案 。它讨论了类似的问题与json 。 同样的方法,使用转换函数创建一个演员,是适用于本案。

你投功能macaddr_ininet_in 。 你需要写一个带包装的SQL函数text ,因为一些刺激性的类型问题提出论点。 见上面的链接。

又见了这个相关答案xml类型 。


您的更新后,我测试了自己的功能,发现他们达到预期效果:

postgres=# CREATE TABLE inetmac (i inet, m macaddr);
CREATE TABLE
postgres=# PREPARE insinet(text) AS INSERT INTO inetmac(i) VALUES ($1);
PREPARE
postgres=# EXECUTE insinet('10.1.1.1');
INSERT 0 1
postgres=# 

......,而是出人意料的是,PG不会隐从投varchartext ,以使用text转换:

postgres=# PREPARE insinet(varchar) AS INSERT INTO inetmac(i) VALUES ($1);
ERROR:  column "i" is of type inet but expression is of type character varying
LINE 1: ...PARE insinet(varchar) AS INSERT INTO inetmac(i) VALUES ($1);
                                                                   ^
HINT:  You will need to rewrite or cast the expression.

如果您使用varchar输入你需要另一组用铸件的varchar ,而不是text输入。

请注意,这不会发生,如果你只是:

INSERT INTO inetmac(i) VALUES ('10.1.1.1');

直接,因为这里'10.1.1.1是伪类的unknown ,而被解释为inet ,因为这就是输入需要。 这有点像一个类型这是隐含强制转换为任何输入功能。 相比之下textvarchar具体类型的PG必须咨询为铸件规则,所以不会产生石膏,这是不行的:

INSERT INTO inetmac(i) VALUES ('10.1.1.1'::text);

我要提出一个关于这个做文章-hackers名单上,这只是痛苦是多么困难的人,从客户端界面使用PostgreSQL的扩展类型。 当然,说客户端接口公开办法告诉JDBC驱动程序的基本类型是什么,但我们是幸运的,如果大部分事情应付极端的基础知识,例如指标和复合键,让类型单独处理的细节。 PG真正需要少一点坚果这一点,或者提供一种方式来指定'unknown'伪类型的参数绑定。

弗斯提出:

  • http://www.postgresql.org/message-id/CACTajFZ8+hg_kom6QiVBa94Kx9L3XUqZ99RdUsHBFkSb1MoCPQ@mail.gmail.com

  • http://www.postgresql.org/message-id/52E87EB0.7010504@2ndquadrant.com



文章来源: Macaddr/Inet type of postgres in slick