New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

infer_schema! reaches the recursion limit easily #1127

Closed
Kazakuri opened this Issue Aug 25, 2017 · 5 comments

Comments

Projects
None yet
3 participants
@Kazakuri

Kazakuri commented Aug 25, 2017

Setup

Versions

  • Rust: rustc 1.21.0-nightly (2bb8fca18 2017-08-23)
  • Diesel: 0.16.0

Problem Description

What are you trying to accomplish?

Having diesel automatically infer the schema for a table with more than ~10 columns.

It looks like the default recursion limit for macros is 64 which can be quite easy to reach with 6 lines of code being generated for each database column.

What is the expected output?

Diesel compiles with no issues.

What is the actual output?

error: recursion limit reached while expanding the macro `table_body`
  --> src\database\schema.rs:1:1
   |
1  | / table! {
2  | |     /// Representation of the `users` table.
3  | |     ///
4  | |     /// (Automatically generated by Diesel.)
...  |
84 | |     }
85 | | }
   | |_^
   |
   = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
   = note: this error originates in a macro outside of the current crate

Steps to reproduce

You can use pretty much any schema, just pad it with a bunch of extra blank documentation comments.

table! {
    /// Representation of the `users` table.
    ///
    /// (Automatically generated by Diesel.)
    users (id) {
        /// The `id` column of the `users` table.
        ///
        /// Its SQL type is `Int4`.
        ///
        /// (Automatically generated by Diesel.)
        id -> Int4,
    }
    ///
    /// etc...
    ///
}

Checklist

  • I have already looked over the issue tracker for similar issues.
@killercup

This comment has been minimized.

Member

killercup commented Aug 25, 2017

That is sadly a problem we can't easily solve in Diesel. For now, just follow the compiler's advice: Add the #![recursion_limit="128"] attribute.

Personally, I set this to 1024 at the first error just to not have to deal with this again. Also, IIRC, the default (64 apparently) was recently increased in rustc, so maybe you'll see this error less often in the future.

That said, we could solve this in Diesel: We'd need to replace the macro with a procedural macro. That is not an easy feat (the macro is quite complex and has a lot of edge cases), and not currently our focus. We'll absolutely look more deeply into this once the next batch of proc-macro features becomes stable in rustc, though.

@killercup killercup closed this Aug 25, 2017

@killercup

This comment has been minimized.

Member

killercup commented Aug 25, 2017

Oh, or do you have a quick fix for this in mind? I've not looked into it more deeply, but if there was an easy change we could make to consume more doc attribute tokens per macro call we'd reduce the table macro's call stack drastically. (Still, not something I really want to spend much time on—there are more pressing matters—but I'd accept a PR for this for sure!)

@mattdeboard

This comment has been minimized.

mattdeboard commented Oct 21, 2017

Hi, so the trouble I'm having is that any table with more than 24 columns (these are extant tables) throws this error. I can run diesel print-schema fine. It outputs the right schema. So since apparently !infer_schema("dotenv:DATABASE_URL", "foo") is equivalent to diesel print-schema -s foo I'm surprised this isn't working correctly.

I tried doing diesel print-schema -s foo > src/models.rs but even then, when I do cargo run, the compiler complains about the recursion limit. Can you explain what the problem is exactly?

edit: Ok apparently the answer is this is a limitation of Rust itself. Here is an explanation with pointers to more detailed explanations.

@Kazakuri

This comment has been minimized.

Kazakuri commented Oct 21, 2017

So basically my understanding of it is that the recursion limit is hit when expanding the table! macro that is generated from the diesel print-schema/!infer_schema("dotenv:DATABASE_URL", "foo") commands.

Like killercup said, the way the table! macro expands is the older(?) recursive style macros instead of a procedural style, so that every line inside the macro body is a recursively parsed.

So unless the macro gets re-written which has a lot of problems in itself, the only real solution is increasing the recursion limit of your program.

@mattdeboard

This comment has been minimized.

mattdeboard commented Oct 21, 2017

@Kazakuri Ya I have added that to the top of my main.rs but it's still happening. Any idea?

Also I added the huge-tables feature to diesel, but STILL getting the error. There are less than 52 columns on the table :-\

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment