Ah, I get it now. This is caused by jOOQ internals calling
TableImpl.where((Condition) null) in order to transform the expression into
an InlineDerivedTable. This is due to various improvements to the feature,
related also to the new Policy feature in jOOQ 3.19:
https://github.com/jOOQ/jOOQ/issues/2682

I guess we'll have to accept Condition? going forward. We're already doing
that in the base class TableImpl, just not in KotlinGenerator generated
code. I've created an issue for this:
https://github.com/jOOQ/jOOQ/issues/16029

This will still fit in this week's (hopefully) 3.19.2 release.

Thanks again for your report.
Lukas



On Mon, Jan 8, 2024 at 2:10 PM Kevin Jones <ke...@knowledgespike.com> wrote:

> Hey Lukas,
>
> of course, I should have put that in originally.
>
> The call site looks like this:
>
> DriverManager.getConnection(connectionString, userName, password).use { conn 
> ->
>
>
>     val context = DSL.using(conn, dialect)
>     val result = context.select(
>         count(),
>         min(MATCHES.MATCHSTARTDATEASOFFSET).`as`("startDate"),
>         max(MATCHES.MATCHSTARTDATEASOFFSET).`as`("endDate"),
>     ).from(MATCHES).where(
>         (MATCHES.HOMETEAMID.`in`(teamsAndOpponents.teamIds)
>             .or(MATCHES.HOMETEAMID.`in`(teamsAndOpponents.opponentIds)))
>             .and(
>                 MATCHES.AWAYTEAMID.`in`(teamsAndOpponents.opponentIds)
>                     .or(MATCHES.AWAYTEAMID.`in`(teamsAndOpponents.teamIds))
>             )
>             .and(
>                 MATCHES.ID.`in`(
>                     select(MATCHSUBTYPE.MATCHID).from(
>                         MATCHSUBTYPE.where(
>                             MATCHSUBTYPE.MATCHTYPE.eq(
>                                 matchSubType
>                             )
>                         )
>                     )
>                 )
>             )
>             .and(MATCHES.VICTORYTYPE.notEqual(6))
>             .and(MATCHES.VICTORYTYPE.notEqual(11))
>             .and(MATCHES.MATCHTYPE.notIn(matchTypesToExclude))
>     ).fetch().first()
>
> Although, If I comment that code out it just fails the next time I use 
> MATCHSUBTYPE
>
>
> Thanks,
>
>
> Kevin
>
>
>
> On Mon, Jan 8, 2024 at 11:49 AM Lukas Eder <lukas.e...@gmail.com> wrote:
>
>> Hi Kevin,
>>
>> Thanks for your message. Can you show your code that calls the where()
>> function?
>>
>> On Mon, Jan 8, 2024 at 12:35 PM Kevin Jones <ke...@knowledgespike.com>
>> wrote:
>>
>>> Hi,
>>>
>>> I'm running on Kotlin 1.9.22 with the Java 17 toolchain.
>>>
>>> I've hitting a problem after upgrading from JOO! 3.18.7 to 3.19.x
>>> Database is MariaDB
>>> Using Gradle as the build system
>>>
>>> My code has not changed but when I run my app now I'm getting this
>>>
>>> java.lang.NullPointerException: Parameter specified as non-null is null:
>>> method com.knowledgespike.db.tables.Matchsubtype.where, parameter condition
>>>
>>> At the point in my code where this exception is thrown nothing is null
>>> (this is in Kotlin and there are no nullable types or platform types
>>> involved at that part of the code.
>>>
>>> If I revert back to 3.18.x and make no further changes then everything
>>> is OK.
>>>
>>> It's not stopping me at the moment as I can stay on 3.18.x
>>>
>>> The stack trace looks like this:
>>>
>>> java.lang.NullPointerException: Parameter specified as non-null is null:
>>> method com.knowledgespike.db.tables.Matchsubtype.where, parameter condition
>>> at org.jooq_3.19.1.MARIADB.debug(Unknown Source)
>>> at com.knowledgespike.db.tables.Matchsubtype.where(Matchsubtype.kt)
>>> at com.knowledgespike.db.tables.Matchsubtype.where(Matchsubtype.kt:46)
>>> at org.jooq.impl.InlineDerivedTable.<init>(InlineDerivedTable.java:66)
>>> at
>>> org.jooq.impl.InlineDerivedTable.derivedTable(InlineDerivedTable.java:221)
>>> at
>>> org.jooq.impl.InlineDerivedTable.inlineDerivedTable(InlineDerivedTable.java:212)
>>> at
>>> org.jooq.impl.InlineDerivedTable.hasInlineDerivedTables(InlineDerivedTable.java:78)
>>> at
>>> org.jooq.impl.InlineDerivedTable.lambda$hasInlineDerivedTables$1(InlineDerivedTable.java:83)
>>> at org.jooq.impl.Tools.findAny(Tools.java:2304)
>>> at org.jooq.impl.Tools.anyMatch(Tools.java:2257)
>>> at
>>> org.jooq.impl.InlineDerivedTable.hasInlineDerivedTables(InlineDerivedTable.java:83)
>>> at
>>> org.jooq.impl.InlineDerivedTable.transformInlineDerivedTables(InlineDerivedTable.java:87)
>>> at
>>> org.jooq.impl.SelectQueryImpl.toSQLReference0(SelectQueryImpl.java:2519)
>>> at
>>> org.jooq.impl.SelectQueryImpl.lambda$toSQLReferenceLimitDefault$8(SelectQueryImpl.java:2043)
>>> at org.jooq.impl.AbstractContext.toggle(AbstractContext.java:414)
>>> at org.jooq.impl.AbstractContext.data(AbstractContext.java:425)
>>> at
>>> org.jooq.impl.SelectQueryImpl.toSQLReferenceLimitDefault(SelectQueryImpl.java:2043)
>>> at org.jooq.impl.SelectQueryImpl.accept0(SelectQueryImpl.java:1885)
>>> at org.jooq.impl.SelectQueryImpl.accept(SelectQueryImpl.java:1556)
>>> at
>>> org.jooq.impl.DefaultRenderContext.visit0(DefaultRenderContext.java:726)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:371)
>>> at
>>> org.jooq.impl.AbstractDelegatingQuery.accept(AbstractDelegatingQuery.java:90)
>>> at
>>> org.jooq.impl.DefaultRenderContext.visit0(DefaultRenderContext.java:726)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:371)
>>> at org.jooq.impl.Tools.visitSubquery(Tools.java:2921)
>>> at org.jooq.impl.Tools.visitSubquery(Tools.java:2894)
>>> at org.jooq.impl.ScalarSubquery.accept(ScalarSubquery.java:92)
>>> at
>>> org.jooq.impl.DefaultRenderContext.visit0(DefaultRenderContext.java:726)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:371)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:281)
>>> at org.jooq.impl.In.lambda$accept$1(In.java:109)
>>> at org.jooq.impl.Eq.acceptCompareCondition(Eq.java:155)
>>> at org.jooq.impl.In.accept(In.java:102)
>>> at
>>> org.jooq.impl.DefaultRenderContext.visit0(DefaultRenderContext.java:726)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:371)
>>> at org.jooq.impl.Expression.acceptAssociative(Expression.java:937)
>>> at org.jooq.impl.And.accept(And.java:118)
>>> at
>>> org.jooq.impl.DefaultRenderContext.visit0(DefaultRenderContext.java:726)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:371)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:276)
>>> at
>>> org.jooq.impl.ConditionProviderImpl.accept(ConditionProviderImpl.java:151)
>>> at
>>> org.jooq.impl.DefaultRenderContext.visit0(DefaultRenderContext.java:726)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:371)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:276)
>>> at
>>> org.jooq.impl.SelectQueryImpl.toSQLReference0(SelectQueryImpl.java:2572)
>>> at
>>> org.jooq.impl.SelectQueryImpl.lambda$toSQLReferenceLimitDefault$8(SelectQueryImpl.java:2043)
>>> at org.jooq.impl.AbstractContext.toggle(AbstractContext.java:414)
>>> at org.jooq.impl.AbstractContext.data(AbstractContext.java:425)
>>> at
>>> org.jooq.impl.SelectQueryImpl.toSQLReferenceLimitDefault(SelectQueryImpl.java:2043)
>>> at org.jooq.impl.SelectQueryImpl.accept0(SelectQueryImpl.java:1885)
>>> at org.jooq.impl.SelectQueryImpl.accept(SelectQueryImpl.java:1556)
>>> at
>>> org.jooq.impl.DefaultRenderContext.visit0(DefaultRenderContext.java:726)
>>> at org.jooq.impl.AbstractContext.visit(AbstractContext.java:371)
>>> at org.jooq.impl.AbstractQuery.getSQL0(AbstractQuery.java:513)
>>> at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:303)
>>> at org.jooq.impl.AbstractResultQuery.fetch(AbstractResultQuery.java:290)
>>> at org.jooq.impl.SelectImpl.fetch(SelectImpl.java:3232)
>>> at
>>> com.knowledgespike.teamvteam.database.ProcessTeams.getCountOfMatchesBetweenTeams(ProcessTeams.kt:163)
>>> at
>>> com.knowledgespike.teamvteam.database.ProcessTeams.process(ProcessTeams.kt:78)
>>> at
>>> com.knowledgespike.teamvteam.Application$Companion$processAllCompetitions$2$4$job$1.invokeSuspend(Application.kt:197)
>>> at
>>> kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
>>> at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
>>> at
>>> kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
>>> at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
>>> at
>>> kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
>>> at
>>> kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
>>> at
>>> kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
>>> at
>>> kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
>>>
>>> and the generated table in question (Matchsubtype) looke like this
>>>
>>> @Suppress("UNCHECKED_CAST")
>>> open class Matchsubtype(
>>> alias: Name,
>>> path: Table<out Record>?,
>>> childPath: ForeignKey<out Record, MatchsubtypeRecord>?,
>>> parentPath: InverseForeignKey<out Record, MatchsubtypeRecord>?,
>>> aliased: Table<MatchsubtypeRecord>?,
>>> parameters: Array<Field<*>?>?,
>>> where: Condition?
>>> ): TableImpl<MatchsubtypeRecord>(
>>> alias,
>>> Cricketarchive.CRICKETARCHIVE,
>>> path,
>>> childPath,
>>> parentPath,
>>> aliased,
>>> parameters,
>>> DSL.comment(""),
>>> TableOptions.table(),
>>> where,
>>> ) {
>>> companion object {
>>>
>>> /**
>>> * The reference instance of <code>cricketarchive.MatchSubType</code>
>>> */
>>> val MATCHSUBTYPE: Matchsubtype = Matchsubtype()
>>> }
>>>
>>> /**
>>> * The class holding records for this type
>>> */
>>> override fun getRecordType(): Class<MatchsubtypeRecord> =
>>> MatchsubtypeRecord::class.java
>>>
>>> /**
>>> * The column <code>cricketarchive.MatchSubType.Id</code>.
>>> */
>>> val ID: TableField<MatchsubtypeRecord, Int?> = createField(DSL.name("Id"),
>>> SQLDataType.INTEGER.nullable(false).identity(true), this, "")
>>>
>>> /**
>>> * The column <code>cricketarchive.MatchSubType.MatchType</code>.
>>> */
>>> val MATCHTYPE: TableField<MatchsubtypeRecord, String?> = createField(DSL
>>> .name("MatchType"), SQLDataType.VARCHAR(20).nullable(false), this, "")
>>>
>>> /**
>>> * The column <code>cricketarchive.MatchSubType.MatchId</code>.
>>> */
>>> val MATCHID: TableField<MatchsubtypeRecord, Int?> = createField(DSL
>>> .name("MatchId"), SQLDataType.INTEGER.nullable(false), this, "")
>>>
>>> private constructor(alias: Name, aliased: Table<MatchsubtypeRecord>?):
>>> this(alias, null, null, null, aliased, null, null)
>>> private constructor(alias: Name, aliased: Table<MatchsubtypeRecord>?,
>>> parameters: Array<Field<*>?>?): this(alias, null, null, null, aliased,
>>> parameters, null)
>>> private constructor(alias: Name, aliased: Table<MatchsubtypeRecord>?,
>>> where: Condition): this(alias, null, null, null, aliased, null, where)
>>>
>>> /**
>>> * Create an aliased <code>cricketarchive.MatchSubType</code> table
>>> * reference
>>> */
>>> constructor(alias: String): this(DSL.name(alias))
>>>
>>> /**
>>> * Create an aliased <code>cricketarchive.MatchSubType</code> table
>>> * reference
>>> */
>>> constructor(alias: Name): this(alias, null)
>>>
>>> /**
>>> * Create a <code>cricketarchive.MatchSubType</code> table reference
>>> */
>>> constructor(): this(DSL.name("MatchSubType"), null)
>>>
>>> constructor(path: Table<out Record>, childPath: ForeignKey<out Record,
>>> MatchsubtypeRecord>?, parentPath: InverseForeignKey<out Record,
>>> MatchsubtypeRecord>?): this(Internal.createPathAlias(path, childPath,
>>> parentPath), path, childPath, parentPath, MATCHSUBTYPE, null, null)
>>>
>>> /**
>>> * A subtype implementing {@link Path} for simplified path-based joins.
>>> */
>>> open class MatchsubtypePath : Matchsubtype, Path<MatchsubtypeRecord> {
>>> constructor(path: Table<out Record>, childPath: ForeignKey<out Record,
>>> MatchsubtypeRecord>?, parentPath: InverseForeignKey<out Record,
>>> MatchsubtypeRecord>?): super(path, childPath, parentPath)
>>> private constructor(alias: Name, aliased: Table<MatchsubtypeRecord>):
>>> super(alias, aliased)
>>> override fun `as`(alias: String): MatchsubtypePath = MatchsubtypePath(
>>> DSL.name(alias), this)
>>> override fun `as`(alias: Name): MatchsubtypePath = MatchsubtypePath(
>>> alias, this)
>>> override fun `as`(alias: Table<*>): MatchsubtypePath = MatchsubtypePath(
>>> alias.qualifiedName, this)
>>> }
>>> override fun getSchema(): Schema? = if (aliased()) null else
>>> Cricketarchive.CRICKETARCHIVE
>>> override fun getIndexes(): List<Index> = listOf(MATCHSUBTYPE_MATCHID,
>>> MATCHSUBTYPE_MATCHTYPE)
>>> override fun getIdentity(): Identity<MatchsubtypeRecord, Int?> = 
>>> super.getIdentity()
>>> as Identity<MatchsubtypeRecord, Int?>
>>> override fun getPrimaryKey(): UniqueKey<MatchsubtypeRecord> =
>>> KEY_MATCHSUBTYPE_PRIMARY
>>> override fun getReferences(): List<ForeignKey<MatchsubtypeRecord, *>> =
>>> listOf(MATCHSUBTYPE_IBFK_1)
>>>
>>> private lateinit var _matches: MatchesPath
>>>
>>> /**
>>> * Get the implicit join path to the <code>cricketarchive.Matches</code>
>>> * table.
>>> */
>>> fun matches(): MatchesPath {
>>> if (!this::_matches.isInitialized)
>>> _matches = MatchesPath(this, MATCHSUBTYPE_IBFK_1, null)
>>>
>>> return _matches;
>>> }
>>>
>>> val matches: MatchesPath
>>> get(): MatchesPath = matches()
>>> override fun `as`(alias: String): Matchsubtype = Matchsubtype(DSL.name(
>>> alias), this)
>>> override fun `as`(alias: Name): Matchsubtype = Matchsubtype(alias, this)
>>> override fun `as`(alias: Table<*>): Matchsubtype = Matchsubtype(alias.
>>> qualifiedName, this)
>>>
>>> /**
>>> * Rename this table
>>> */
>>> override fun rename(name: String): Matchsubtype = Matchsubtype(DSL.name(
>>> name), null)
>>>
>>> /**
>>> * Rename this table
>>> */
>>> override fun rename(name: Name): Matchsubtype = Matchsubtype(name, null)
>>>
>>> /**
>>> * Rename this table
>>> */
>>> override fun rename(name: Table<*>): Matchsubtype = Matchsubtype(name.
>>> qualifiedName, null)
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> override fun where(condition: Condition): Matchsubtype = Matchsubtype(
>>> qualifiedName, if (aliased()) this else null, condition)
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> override fun where(conditions: Collection<Condition>): Matchsubtype =
>>> where(DSL.and(conditions))
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> override fun where(vararg conditions: Condition): Matchsubtype = where(
>>> DSL.and(*conditions))
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> override fun where(condition: Field<Boolean?>): Matchsubtype = where(DSL
>>> .condition(condition))
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> @PlainSQL override fun where(condition: SQL): Matchsubtype = where(DSL
>>> .condition(condition))
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> @PlainSQL override fun where(@Stringly.SQL condition: String): Matchsubtype
>>> = where(DSL.condition(condition))
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> @PlainSQL override fun where(@Stringly.SQL condition: String, vararg
>>> binds: Any?): Matchsubtype = where(DSL.condition(condition, *binds))
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> @PlainSQL override fun where(@Stringly.SQL condition: String, vararg
>>> parts: QueryPart): Matchsubtype = where(DSL.condition(condition, *parts
>>> ))
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> override fun whereExists(select: Select<*>): Matchsubtype = where(DSL
>>> .exists(select))
>>>
>>> /**
>>> * Create an inline derived table from this table
>>> */
>>> override fun whereNotExists(select: Select<*>): Matchsubtype = where(DSL
>>> .notExists(select))
>>> }
>>>
>>> HTH
>>>
>>> Thanks
>>>
>>> Kevin
>>>
>>>
>>>
>>>
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "jOOQ User Group" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to jooq-user+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/jooq-user/72e33f7d-d3de-41a0-aad7-a420b8984ed6n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/jooq-user/72e33f7d-d3de-41a0-aad7-a420b8984ed6n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "jOOQ User Group" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to jooq-user+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/jooq-user/CAB4ELO6J95B6Od7pL8APup8_hyk0L977_0-tyky%2Bwtoy4SxFZQ%40mail.gmail.com
>> <https://groups.google.com/d/msgid/jooq-user/CAB4ELO6J95B6Od7pL8APup8_hyk0L977_0-tyky%2Bwtoy4SxFZQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>
>
> --
> Kevin Jones
> KnowledgeSpike
>
> --
> You received this message because you are subscribed to the Google Groups
> "jOOQ User Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to jooq-user+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jooq-user/CAKT%3DYsMcSi1Yu-QZn7oHi%2BQMwHDNiQsJgNZ7bihh9k_fj5Z1tA%40mail.gmail.com
> <https://groups.google.com/d/msgid/jooq-user/CAKT%3DYsMcSi1Yu-QZn7oHi%2BQMwHDNiQsJgNZ7bihh9k_fj5Z1tA%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups "jOOQ 
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jooq-user+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jooq-user/CAB4ELO46ZF2QmbwAbx9XhgKwsYKjVA2JJG28yyx9y_aVaT5WSw%40mail.gmail.com.

Reply via email to