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

Query with a lot of conditions causes StackOverflowError #1606

Open
takezoe opened this Issue Sep 10, 2016 · 5 comments

Comments

Projects
None yet
7 participants
@takezoe

takezoe commented Sep 10, 2016

With Slick 3.1.1, I got StackOverflowError for a query which has a lot of conditions.

Code to reproduce easily is below:

val seq = Range(1, 500)
Accounts.filter { t => seq.map { x => t.userId === x.bind }.reduce(_ || _)}.list

An error caused by above query is:

java.lang.StackOverflowError
    at scala.collection.immutable.Set$class.seq(Set.scala:55)
    at scala.collection.immutable.Set$EmptySet$.seq(Set.scala:68)
    at scala.collection.immutable.Set$EmptySet$.seq(Set.scala:68)
    at scala.collection.SetLike$class.$plus$plus(SetLike.scala:141)
    at scala.collection.AbstractSet.$plus$plus(Set.scala:47)
    at slick.compiler.ExpandSums.slick$compiler$ExpandSums$$tr$1(ExpandSums.scala:27)
    at slick.compiler.ExpandSums$$anonfun$7.apply(ExpandSums.scala:32)
    at slick.compiler.ExpandSums$$anonfun$7.apply(ExpandSums.scala:32)
    at slick.util.ConstArray.endoMap(ConstArray.scala:122)
    at slick.ast.Node$class.mapChildren(Node.scala:51)
    at slick.ast.Apply.mapChildren(Node.scala:539)
    at slick.compiler.ExpandSums.slick$compiler$ExpandSums$$tr$1(ExpandSums.scala:32)
    at slick.compiler.ExpandSums$$anonfun$7.apply(ExpandSums.scala:32)
    at slick.compiler.ExpandSums$$anonfun$7.apply(ExpandSums.scala:32)
    at slick.util.ConstArray.endoMap(ConstArray.scala:122)
    at slick.ast.Node$class.mapChildren(Node.scala:51)
    at slick.ast.Apply.mapChildren(Node.scala:539)

I tried decreasing condition. Then I got another StackOverflowError.

val seq = Range(1, 200)
Accounts.filter { t => seq.map { x => t.userId === x.bind }.reduce(_ || _)}.list

An error caused by above query is:

java.lang.StackOverflowError
    at slick.driver.JdbcStatementBuilderComponent$QueryBuilder.expr(JdbcStatementBuilderComponent.scala:306)
    at slick.driver.PostgresDriver$QueryBuilder.expr(PostgresDriver.scala:164)
    at slick.driver.JdbcStatementBuilderComponent$QueryBuilder$$anonfun$expr$7.apply(JdbcStatementBuilderComponent.scala:376)
    at slick.driver.JdbcStatementBuilderComponent$QueryBuilder$$anonfun$expr$7.apply(JdbcStatementBuilderComponent.scala:376)
    at slick.util.SQLBuilder.sep(SQLBuilder.scala:31)
    at slick.driver.JdbcStatementBuilderComponent$QueryBuilder.expr(JdbcStatementBuilderComponent.scala:376)
    at slick.driver.PostgresDriver$QueryBuilder.expr(PostgresDriver.scala:164)
    at slick.driver.JdbcStatementBuilderComponent$QueryBuilder$$anonfun$expr$7.apply(JdbcStatementBuilderComponent.scala:376)
    at slick.driver.JdbcStatementBuilderComponent$QueryBuilder$$anonfun$expr$7.apply(JdbcStatementBuilderComponent.scala:376)
    at slick.util.SQLBuilder.sep(SQLBuilder.scala:31)
@raam86

This comment has been minimized.

Show comment
Hide comment
@raam86

raam86 commented Oct 24, 2016

+1

@cvogt cvogt added the bug label Oct 24, 2016

@mycentrio

This comment has been minimized.

Show comment
Hide comment
@mycentrio

mycentrio commented Nov 30, 2016

+1

@spilliton

This comment has been minimized.

Show comment
Hide comment
@spilliton

spilliton commented Oct 24, 2017

Samesies

@takezoe

This comment has been minimized.

Show comment
Hide comment
@takezoe

takezoe Aug 12, 2018

I found a workaround that replacing consecutive ORs with IN clause as below:

val seq = Range(1, 500)

// This causes StackOverflowError
Accounts.filter { t => seq.map { x => t.userId === x.bind }.reduce(_ || _)}.list

// This works
Accounts.filter { t => t.userId inSetBind(seq) }.list

However this isn't a perfect workaround because not all queries can be rewritten with IN clause. Also some databases have the limitation of number of IN parameters.

takezoe commented Aug 12, 2018

I found a workaround that replacing consecutive ORs with IN clause as below:

val seq = Range(1, 500)

// This causes StackOverflowError
Accounts.filter { t => seq.map { x => t.userId === x.bind }.reduce(_ || _)}.list

// This works
Accounts.filter { t => t.userId inSetBind(seq) }.list

However this isn't a perfect workaround because not all queries can be rewritten with IN clause. Also some databases have the limitation of number of IN parameters.

@dominics

This comment has been minimized.

Show comment
Hide comment
@dominics

dominics Aug 22, 2018

However this isn't a perfect workaround because not all queries can be rewritten with IN clause

Specifically, #517 means compound primary keys can't be queried with inSet

dominics commented Aug 22, 2018

However this isn't a perfect workaround because not all queries can be rewritten with IN clause

Specifically, #517 means compound primary keys can't be queried with inSet

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