Skip to content
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

[Bug]: Crash from Stack overflow due to AQL fails beyond certain operand counts in FROM syntax #608

Open
Kelerchian opened this issue Nov 23, 2023 · 2 comments
Assignees
Labels

Comments

@Kelerchian
Copy link
Contributor

Kelerchian commented Nov 23, 2023

Product

Actyx

Operating System

None

Current behavior

Let us formulate a term first: Tagchain*[n], which stands for an operation of multiple tags with n number of operand.

For example FROM [Tagchain*2] stands for FROM 'tag1' | 'tag2'

Problem: Tagchain*[n] fails with a certain limit of n. The limit decreases following this condition:

  • The Tagchain is a nested operand (-1 for each level of nesting)
  • The Tagchain is a left operand

Limit example:

  • FROM [Tagchain*1006] does not result in
  • FROM [Tagchain*1007] results in stack overflow for exceeding the base limit

Limit decrease behavior example:

FROM [Tagchain*[limit = 1006]]
// 1006 is base limit
FROM 'sometag' & ( [Tagchain*[limit = 1005]] )
// -1 to being nested operand
FROM 'sometag' & ( [Tagchain*[limit = 1004]] ) & 'someothertag'
// -1 to being nested operand
// -1 to being left operand
`FROM ( [Tagchain*[limit = 1004]] ) & ( [Tagchain*[limit = 1004]] ) & ( [Tagchain*[limit = 1004]] ) & ( [Tagchain*[limit = 1005]] )
// right most: -1 being nested operand
// rest: -2 for being both nested operand and left operand
FROM ( [Tagchain*[limit = 1004]] ) & ( ( Tagchain*[limit = 1003] ) & ( Tagchain*[limit = 1004] ) )
// left most: -2 for being both nested operand and left operand
// mid: -1 for being left operand, -2 for being a level-2 nested operand 
// right:  -2 for being a level-2 nested operand 

Expected behavior

Should not overflow?

How to reproduce

Use Actyx["queryAql"] to call AQL with the samples from current behavior section.

For example:

    const sdk = await ActyxSDK.Actyx.of({
        appId: "com.example.trial",
        displayName: "com.example.trial",
        version: "0.1.0",
    });

    const tc = (x: number) =>
        new Array(x)
            .fill(null)
            .map((_, i) => `"tag:${i}"`)
            .join(" | ");

    await sdk.queryAql({
        query: `FROM (${tc(1005)}) & ((${tc(1003)}) & (${tc(1004)}))`,
    });
    sdk.dispose();

Additional notes

  • UX important consideration: While this behavior is not advertised in Actyx docs, this behavior is a potential stand-in for the absent equivalent of WHERE IN syntax in SQL.

  • There might also be limit decrease factor that I did not catch since these rules are derived from observation of phenomena with limited samples.

  • This limit has only been tested in linux-amd64 build of Actyx

@Kelerchian Kelerchian added the Bug label Nov 23, 2023
@Kelerchian Kelerchian self-assigned this Dec 8, 2023
@Kelerchian
Copy link
Contributor Author

Partial mitigation is done in this PR #623.
Now databank does not entirely crash because of stack overflow, but the related query fails with an error/diagnostic event.

@Kelerchian
Copy link
Contributor Author

I'm revisiting the stack overflow thing to see if I can use stacker::grow and then I remembered that async works differently:

  • async {}.boxed() only constructs the future "state machine"
  • The recursion happens ONLY when .await of the future is called
  • Wrapping the async {}.boxed() inside a stacker::grow only put the construction process and not the recursion itself into the new stack
  • Meanwhile .await is not available because stacker::grow accepts a sync-closure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
1 participant