vlecoq-v
vlecoq-v

Reputation: 121

How does Exposed handle bind parameters?

Hello to all of you fine folks

I recently learned about the importance of bind parameters in sql queries for optimization.

I use kotlin-exposed in a DSL setup and when I follow the basic query example like so:

TExportJobs
    .select { TExportJobs.id eq request.id.toInt() }.firstOrNull()

The printed query does not use bind parameters:

SELECT export_jobs.id, ... FROM export_jobs WHERE export_jobs.id = 4

Is exposed using bind paramter under the hood? Is my setup likely not formatted correctly?

Here is my example table object:

object TExportJobs: IntIdTable("export_jobs") {
    val userEmail = varchar("user_email", 128).index()
}

Upvotes: 1

Views: 632

Answers (1)

vlecoq-v
vlecoq-v

Reputation: 121

Found it!

The sqlLogger interface (org.jetbrains.exposed.sql.SqlLogger) uses an expandArgs method from statementContext (org.jetbrains.exposed.sql.statements.StatementContext) that replaces '?' parameters.

So it is done under the hood

buildString {
        val quoteStack = Stack<Char>()
        var lastPos = 0
        for (i in 0..sql.length - 1) {
            val char = sql[i]
            if (char == '?') {
                if (quoteStack.isEmpty()) {
                    append(sql.substring(lastPos, i))
                    lastPos = i + 1
                    val (col, value) = iterator.next()
                    append(col.valueToString(value))
                }
                continue
            }

            if (char == '\'' || char == '\"') {
                if (quoteStack.isEmpty()) {
                    quoteStack.push(char)
                } else {
                    val currentQuote = quoteStack.peek()
                    if (currentQuote == char)
                        quoteStack.pop()
                    else
                        quoteStack.push(char)
                }
            }
        }

        if (lastPos < sql.length)
            append(sql.substring(lastPos))
    }

Upvotes: 2

Related Questions