Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upSupport enumerated types #343
Comments
This comment has been minimized.
|
FYI in SQLite you could try to do something similar with a text column and CREATE TABLE track (
id INTEGER PRIMARY KEY,
track TEXT CHECK(track IN ('download', 'stream')) NOT NULL
); |
This comment has been minimized.
carsonmyers
commented
Dec 19, 2016
|
Is there currently a good way around this? Like a custom de/serializer? |
This comment has been minimized.
|
As an outsider who looked through the code to figure out if there is a way to do this, it appears that supporting a user-defined Postgres type requires knowing the object identifier that is in use for that type. In the case of enums, this requires extracting information from
select pt.typname, pt.typtype, pt.typcategory, pe.enumlabel, pt.oid
from pg_type pt
inner join pg_enum pe on pe.enumtypid = pt.oid
where pt.typcategory = 'E';
Since runtime database information is needed, some sort of codegen macro along the lines of |
This comment has been minimized.
|
I've put together a rough, partial implementation of Postgres enum support, which creates a macro called Unfortunately, there are currently a few assumptions about type definitions that make it difficult to use custom enum types in tables:
I haven't actually done the legwork necessary to know how to deal with encoding or decoding enum values to/from raw bytes for handoff with Postgres. I assume that this will essentially entail handling type-tagged integers. Finally, handling schemas correctly is on the back burner until everything else is taken care of. It'll require an additional join. |
This comment has been minimized.
|
I've been able to address (1) and (2), but getting everything working in the integration tests has run head-long into #348. If anyone has successfully figured out the minimal footprint of traits needed to make a simple, atomic SQL type, some documentation or example code would be welcome. |
This comment has been minimized.
|
Oh, wow! That sounds great! Thank you for digging into this!
Currently, the SQL types and the Rust types are divided; the table! macro
will contain a SQL type and a struct with e.g. Queryable has the ability to
deserialize these types into the actual Rust types it contains. What you
described sound like for an inferred enum, SQL and Rust type are the same.
I haven't thought much about this, maybe it makes sense. Just thought I'd
mention it.
@jethrogb was [on Gitter][1] a few weeks ago and wanted to implement a
custom type. Maybe you can get some additional information from the log
there.
Happy holidays!
[1]: https://gitter.im/diesel-rs/diesel?at=5849d6a8be9d43bc633778da
Stu Black <notifications@github.com> schrieb am Sa. 24. Dez. 2016 um 07:50:
… I've been able to address (1) and (2), but getting everything working in
the integration tests has run head-long into #348
<#348>. If anyone has
successfully figured out the minimal footprint of traits needed to make a
simple, atomic SQL type, some documentation or example code would be
welcome.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#343 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABOX8AJ9cTIqXkGKoakndQpU0iVYeriks5rLMCugaJpZM4IlWGG>
.
|
This comment has been minimized.
|
My pleasure. I suspect that it will not be too difficult to extend this work to create Rust struct types automatically from user-created composite types in Postgres, and I'm also considering that.
That is exactly what the current implementation does. I have wondered a bit as to whether this is really the right thing to do, but I still believe it is. It might be a good idea store some metadata with the generated type (probably in a static impl of some There is probably a long-range design issue lurking behind the scenes here. I've already run into a few instances of code assuming that SQL types live in
I think I have the necessary traits implemented, but I'm still running into problems. A second pair of eyes will help once I have permission to share a patch. |
This comment has been minimized.
kybishop
commented
Jan 5, 2017
This comment has been minimized.
|
I just got the OK to contribute and copyright release from my friendly neighborhood corporate overlords, so I'll reinstate my fork soon. |
This comment has been minimized.
|
Feature bumps and deprecations from the 1.15 release and deprecation of I've pushed what was (more or less) working back in December to the custom_types_in_database_columns branch of my fork. I'd open a PR, but I don't think things are quite working yet. What's the deal with the test script? |
This comment has been minimized.
|
Try rebasing on master and running on beta |
This comment has been minimized.
|
The most significant test failures seem to be #571, which is not directly related to adding support for enums. With a fix patched in locally, the problem I am currently running into is that types which are declared in a dummy namespace by infer_enums!("dotenv:DATABASE_URL");
pub use self::__diesel_infer_enums::UserType; // Inserted by hand; shows that the type exists.
infer_schema!("dotenv:DATABASE_URL"); // Errors here because UserType isn't known.I have tried changing the table declarations generated by
I suspect that converting a literal "self" or "super" with A couple of different hacks (running I'll have to try to boil this down to a simple example to verify it, but this is acting an awful lot like the enum types whose declarations I'm generating are not visible in the code that generates the table schema. |
This comment has been minimized.
|
You can work around the question of how to look up dynamically generated types by requiring that the user specify the module where any non-builtin types can be found, so that's how things now work. This isn't great (and raises questions about how to deal with types derived from schemas, which one might reasonably want to live in sub-modules), but it looks like it works for now. I must have been recollecting wishfully when I said that I thought most tests were passing earlier. I'm now running into some deficiencies in implementing the interfaces needed to make a custom type queryable/insertable/updateable/etc. This is all in |
This comment has been minimized.
|
I will continue further discussion of the implementation I'm working on in #580. |
dstu
referenced this issue
Jan 15, 2017
Closed
Implementing `diesel::Expression`, etc., for custom types outside diesel? #562
This comment has been minimized.
|
#580 has been closed as discussed there. (It needed to be factored apart and fell too far behind diesel main.) I have been swamped with events at work and in my personal life, and this has prevented me from pulling a set of new PRs together. I'd be happy to discuss this further with anyone who is interested in getting a PR together sooner, and I will share whatever I can put together, when I can. |
This comment has been minimized.
coder543
commented
Jun 2, 2017
|
I just encountered this bug. Not having this feature means I'm (at least for now) switching from strongly-typed enums in my database to varchars... which is not great. I would love to have this feature. |
This comment has been minimized.
dsvensson
commented
Aug 13, 2017
•
|
@dstu it would be nice if inferring schema is not required, other than perhaps creating a first example of a Rust enum (which might then be renamed, while keeping some annotation or so for the name used in Postgres... mapping)... and then connecting the dots upon actual connect, rather than having any kind of ids hardcoded. Or did I misunderstand you there when you mentioned "Since runtime database information is needed, some sort of codegen macro along the lines of infer_schema! seems necessary" ? |
This comment has been minimized.
turboladen
commented
Oct 26, 2017
|
FWIW, if working with pg enums in diesel meant having to define a rust annotated struct (or... enum?) to represent the pg enum, that'd seem totally reasonable to me. |
This comment has been minimized.
|
So I'm going to close this as a duplicate of #162. At this point, everything needed for absolute minimum "support" for PG enums is there. We even have a test case for this in Diesel itself. I'm aware that this requires more code than people would like right now (this is true of implementing new types in general, not just enums). #162 is the tracking issue for that, and is going to be the main focus of 1.1. Ideally you'll just need to provide an impl of At this point, I do not want to provide any special support for PG enums (e.g. TL;DR: Custom types in general are "supported". It's going to get more ergonomic in 1.1. We aren't going to provide special handling for PG enums. |
sgrif
closed this
Dec 16, 2017
This comment has been minimized.
coder543
commented
Dec 16, 2017
|
I don't necessarily agree with the decision, but I appreciate the way you're approaching the situation. I personally think enums are important enough to be a special case, but as long as it is possible to support them in Diesel, that's good enough for me. As you said, an outside crate could be developed to provide an opinionated solution to this issue that could act as a way to reduce boilerplate for those who are interested. Looking at the example code you linked to, it seems pretty reasonable to me. My only real question at this point: is using |
This comment has been minimized.
|
Not at the moment, but using `diesel print-schema` works
…On Sat, Dec 16, 2017, 3:11 PM Josh Leverette ***@***.***> wrote:
I don't necessarily agree with the decision, but I appreciate the way
you're approaching the situation. I personally think enums are important
enough to be a special case, but as long as it is *possible* to support
them in Diesel, that's good enough for me. As you said, an outside crate
could be developed to provide an opinionated solution to this issue that
could act as a way to reduce boilerplate for those who are interested.
Looking at the example code you linked to, it seems pretty reasonable to
me. My only real question at this point: is using infer_schema! is
possible with a database that has custom types in some/all of the tables?
I've been busy with other projects for awhile now, but from what I recall,
infer_schema! might have actually generated code which could not compile
in such cases, and I don't remember finding a way to inject the custom
types into the namespace that infer_schema! created.
—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
<#343 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABdWK3CVhaMcOvmOk96IWmiPhbmxc-mqks5tBD_6gaJpZM4IlWGG>
.
|
This comment has been minimized.
adwhit
commented
Jan 4, 2018
|
Just thought I'd mention to anyone who comes across this issue that I've made a crate to derive the necessary trait impls, it's up on crates.io. Feedback welcome. |
mkroman commentedMay 24, 2016
Diesel does not currently support enumerated types created with PostgreSQL.
Documentation on enumerated types can be found here.
More documentation on
CREATE TYPEcan be found here.Example
When compiling, the generated code expects a type named like the custom data type.