Skip to content

Closing a connection on a query without columns hangs forever

This issue might be related to this one: #152 (closed)

When closing the connection for a query with no columns at all (i.e. "". or "-- just a comment") the conn.Close() method hangs forever.

Example code (and a comparison with to the SQLite driver from mattn)

package main

import (
	"context"
	"database/sql"
	"fmt"

	_ "github.com/mattn/go-sqlite3"
	_ "modernc.org/sqlite"
)

func runQuery(driver string, query string) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("!!! panic occurred:", err)
		}
	}()

	fmt.Printf("\nQuery: '%s'\n", query)
	db, err := sql.Open(driver, ":memory:")
	if err != nil {
		fmt.Printf("Error opening the database: %v\n", err)
		return
	}
	defer db.Close()
	fmt.Println("Opened the database")

	conn, err := db.Conn(context.TODO())
	if err != nil {
		fmt.Println("Error getting a connection", err)
		return
	}
	defer conn.Close()

	rows, err := conn.QueryContext(context.TODO(), query)
	if err != nil {
		fmt.Printf("Error running the query: %v\n", err)
		return
	}
	defer rows.Close()
	fmt.Println("Ran the query")

	columns, err := rows.Columns()
	if err != nil {
		fmt.Printf("Error getting columns: %v\n", err)
		return
	}
	if len(columns) == 0 {
		fmt.Println("No columns available")
		return
	}

	for rows.Next() {
		fmt.Println("Scanning rows")
		err := rows.Scan()
		if err != nil {
			fmt.Printf("Error scanning rows: %v\n", err)
			return
		}
	}

	err = rows.Err()
	if err != nil {
		fmt.Printf("Error with the rows: %v\n", err)
		return
	}
	fmt.Println("Scanned the rows")
}

func main() {
	fmt.Println("Starting")

	fmt.Println("-- github.com/mattn/go-sqlite3 --")
	runQuery("sqlite3", "SELECT 1 WHERE false")
	runQuery("sqlite3", "-- just a comment")
	runQuery("sqlite3", "")

	fmt.Println("-- modernc.org/sqlite --")
	runQuery("sqlite", "SELECT 1 WHERE false")
	runQuery("sqlite", "-- just a comment")
	runQuery("sqlite", "")

	fmt.Println("Finished")
}