Merge pull request #1392 from mattn/fix-issue-1390-query-comment-panic

Fix panic when querying input with no SQL (only comments/whitespace)
diff --git a/sqlite3.go b/sqlite3.go
index 1a5433c..d59541b 100644
--- a/sqlite3.go
+++ b/sqlite3.go
@@ -1017,25 +1017,37 @@
 		if err != nil {
 			return nil, err
 		}
-		s.(*SQLiteStmt).cls = true
+		ss := s.(*SQLiteStmt)
+		ss.cls = true
+		// sqlite3_prepare_v2 returns SQLITE_OK with a NULL statement handle
+		// when the input is empty or contains only whitespace/comments.
+		if ss.s == nil {
+			tail := ss.t
+			ss.Close()
+			if tail == "" {
+				return &SQLiteRows{cls: true, ctx: ctx}, nil
+			}
+			query = tail
+			continue
+		}
 		na := s.NumInput()
 		if len(args)-start < na {
-			s.Close()
+			ss.Close()
 			return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)-start)
 		}
 		stmtArgs := stmtArgs(args, start, na)
-		rows, err := s.(*SQLiteStmt).query(ctx, stmtArgs)
+		rows, err := ss.query(ctx, stmtArgs)
 		if err != nil && err != driver.ErrSkip {
-			s.Close()
+			ss.Close()
 			return rows, err
 		}
 		start += na
-		tail := s.(*SQLiteStmt).t
+		tail := ss.t
 		if tail == "" {
 			return rows, nil
 		}
 		rows.Close()
-		s.Close()
+		ss.Close()
 		query = tail
 	}
 }
@@ -2441,6 +2453,9 @@
 
 // Columns return column names.
 func (rc *SQLiteRows) Columns() []string {
+	if rc.s == nil {
+		return rc.cols
+	}
 	rc.s.mu.Lock()
 	defer rc.s.mu.Unlock()
 	if rc.s.s != nil && int(rc.nc) != len(rc.cols) {
@@ -2464,6 +2479,9 @@
 
 // DeclTypes return column types.
 func (rc *SQLiteRows) DeclTypes() []string {
+	if rc.s == nil {
+		return rc.decltype
+	}
 	rc.s.mu.Lock()
 	defer rc.s.mu.Unlock()
 	return rc.declTypes()
@@ -2471,6 +2489,9 @@
 
 // Next move cursor to next. Attempts to honor context timeout from QueryContext call.
 func (rc *SQLiteRows) Next(dest []driver.Value) error {
+	if rc.s == nil {
+		return io.EOF
+	}
 	rc.s.mu.Lock()
 	defer rc.s.mu.Unlock()
 
diff --git a/sqlite3_test.go b/sqlite3_test.go
index 852aa10..ac81458 100644
--- a/sqlite3_test.go
+++ b/sqlite3_test.go
@@ -2065,6 +2065,40 @@
 	}
 }
 
+// https://github.com/mattn/go-sqlite3/issues/1390
+// sqlite3_prepare_v2 returns SQLITE_OK with a NULL statement handle when the
+// input contains no SQL (only whitespace or comments). Querying such input
+// must not panic.
+func TestQueryCommentOnly(t *testing.T) {
+	db, err := sql.Open("sqlite3", ":memory:")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer db.Close()
+
+	cases := []string{"", "   ", "-- comment", "---- comment\n", "/* block */"}
+	for _, q := range cases {
+		var x int
+		if err := db.QueryRow(q).Scan(&x); err != sql.ErrNoRows {
+			t.Errorf("QueryRow(%q): expected ErrNoRows, got %v", q, err)
+		}
+
+		rows, err := db.Query(q)
+		if err != nil {
+			t.Errorf("Query(%q): unexpected error: %v", q, err)
+			continue
+		}
+		if rows.Next() {
+			t.Errorf("Query(%q): expected no rows", q)
+		}
+		rows.Close()
+
+		if _, err := db.Exec(q); err != nil {
+			t.Errorf("Exec(%q): unexpected error: %v", q, err)
+		}
+	}
+}
+
 var customFunctionOnce sync.Once
 
 func BenchmarkCustomFunctions(b *testing.B) {