surrealdb / surrealdb

A scalable, distributed, collaborative, document-graph database, for the realtime web
https://surrealdb.com
Other
27.49k stars 895 forks source link

Bug: stack overflows on computed graph query in Rust SDK, but not in CLI #2920

Open teenjuna opened 1 year ago

teenjuna commented 1 year ago

Describe the bug

I was trying to implement a schema, where one of the table's fields returns a value from a graph query. It works nicely on in-memory CLI repl, but when used inside Rust SDK (tested kv-mem and kv-rocksdb), this error is returned:

thread 'tokio-runtime-worker' has overflowed its stack
fatal runtime error: stack overflow
fish: Job 1, 'cargo run' terminated by signal SIGABRT (Abort)

Both CLI and Rust SDK are latest stable 1.0. I also tried Rust SDK from master, the issue stays the same.

Steps to reproduce

This the schema and sequence of statements:

DEFINE TABLE product SCHEMAFULL;
DEFINE FIELD price ON product TYPE object;
DEFINE FIELD price.normal ON product TYPE option<float>
    ASSERT $value == NONE OR $value > 0;
DEFINE FIELD price.discounted ON product
    VALUE {
        RETURN IF price.discount {
            price.normal - price.normal * price.discount / 100f;
        } ELSE {
            price.normal;
        };
    };
DEFINE FIELD price.discount ON product
    VALUE fn::product::discount(id);

DEFINE FUNCTION fn::product::discount($product: record<product>) {
    LET $discounts = array::flatten((SELECT VALUE <-affects<-discount FROM $product FETCH discount));
    LET $active_discounts = SELECT VALUE value FROM $discounts WHERE active = true;
    RETURN array::max($active_discounts);
};

DEFINE TABLE discount SCHEMAFULL;
DEFINE FIELD value ON discount TYPE float
    ASSERT $value >= 0 AND $value <= 100;
DEFINE FIELD start ON discount TYPE option<datetime>;
DEFINE FIELD end ON discount TYPE option<datetime>;
DEFINE FIELD active ON discount
    VALUE <future> {
        LET $now = time::now();
        IF start != NONE AND end != NONE {
            RETURN $now >= start AND $now <= end;
        } ELSE IF start != NONE {
            RETURN $now >= start;    
        } ELSE IF end != NONE {
            RETURN $now <= end;
        };
        RETURN true;
    };

create product:1 set price.normal = 100;
create discount:1 set value = 50;
relate discount:1->affects->product:1;
update product:1;

Expected behaviour

Rust SDK should not overflow.

SurrealDB version

1.0.0+20230913.54aedcd for macos on aarch64

Contact Details

No response

Is there an existing issue for this?

Code of Conduct

teenjuna commented 1 year ago

2637 is kind of similar and might be related.

teenjuna commented 1 year ago

I should also note that if I change product.price.discount to be <future>, it also works in CLI, but overflows in SDK:

DEFINE FIELD price.discount ON product
    VALUE <future> { RETURN fn::product::discount(id) };
rushmorem commented 1 year ago

The CLI also uses the SDK @teenjuna. I think it's not happening in the CLI because it increases the stack size.

teenjuna commented 1 year ago

I kind of suspected that, but didn't think that my query is that complex. Perhaps this should be mentioned in docs in the next release? Anyway, thank you, @rushmorem. The issue I mentioned above might require the same fix on user-side. Should I close this now?

rushmorem commented 1 year ago

That's a good idea @teenjuna. I think we should hold off closing this until it's either documented or we find a way to fix it somehow. Ideally I would hope for the latter. Trying to determine whether a query might or might not need a bigger stack size ahead of time sounds like a pain.

rynoV commented 1 month ago

I also ran into this when trying to get the result of a recursive function back from the sdk, and increasing the stack size fixed it (thank you!)

Worth noting that when using #[tokio::test] it runs in the single thread runtime by default, which could also cause similar issues as noted here