My application uses slick (v2.0.0) to manage a postgresql (9.1) database.
One of my tables contains network devices and therefore mac- and ip-addresses. I used the postgres types macaddr
and inet
as they seemed like the perfect tool for the task. Now I want to use slick with lifted emebedding but struggle to define my tables. When I auto generated the code for my tables I noticed that String
was used instead of those types but didn't mind.
This works fine for reading from the DB but when I try to update or insert a row it causes
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.
wich seems pretty logical.
Now the question is how can I tell slick that:
- This collumn is actually of type
macaddr
/inet
or
- This collumn needs to be casted before insertion but can otherwise be treated as a string
?
Update:
As Craig described I have created implicit casts using wrapper functions around macaddr_in
and inet_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 is still exactly the same as shown above.
Commads to reproduce:
in 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:
I narrowed it down to a permission error because if I run as user 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
but if I try to run it as the user that actually tries to insert
mydb=> insert into test values ('1.1.1.1'::text, '00:00:00:00:00:00'::text);
ERROR: permission denied for relation test
when setting up the database I had run:
template1=# GRANT ALL PRIVILEGES ON DATABASE mydb to myuser;
Update3:
Update2 turned out to be only the problem because the created table was owned by postgres
instead of myuser