siyuan-note/siyuan · warning

SQL statement is empty

Error message

SQL statement is empty

What it means

Returned by checkReadonlyStatement when the SQL string is empty after TrimSpace. This is the first guard before any SQLite prepare — it refuses to run an empty/whitespace-only statement. Used by the read-only query validation path (CheckReadonlyStatement / CheckReadonlyStatementInBox / CheckAssetContentReadonlyStatement).

Source

Thrown at kernel/sql/stmt_validate.go:188

// CheckAssetContentReadonlyStatement 在资源文件内容数据库连接上检查 SQL 是否只读。
func CheckAssetContentReadonlyStatement(stmt string) error {
	return checkReadonlyStatement(stmt, assetContentDB)
}

// CheckReadonlyStatementInBox 在指定笔记本对应的数据库连接上检查 SQL 是否只读。
func CheckReadonlyStatementInBox(stmt, boxID string) error {
	targetDB := db
	if boxDB := GetEncryptedDB(boxID); nil != boxDB {
		targetDB = boxDB
	} else if IsEncryptedBoxFn != nil && IsEncryptedBoxFn(boxID) {
		return errors.New("encrypted box db not opened for box " + boxID)
	}
	return checkReadonlyStatement(stmt, targetDB)
}

func checkReadonlyStatement(stmt string, targetDB *sql.DB) error {
	if strings.TrimSpace(stmt) == "" {
		return errors.New("SQL statement is empty")
	}
	if !isReadonlyQueryStatement(stmt) {
		return errors.New("SQL statement is not a read-only query")
	}
	if nil == targetDB {
		return errors.New("database is nil")
	}
	ctx := context.Background()
	conn, err := targetDB.Conn(ctx)
	if err != nil {
		return err
	}
	defer conn.Close()

	return conn.Raw(func(dc any) error {
		sqliteConn, ok := dc.(*sqlite3.SQLiteConn)
		if !ok {
			return fmt.Errorf("SQL driver connection type is unexpected: %T", dc)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Provide a non-empty SELECT/WITH query string.
  2. Guard the caller: skip the API call when strings.TrimSpace(stmt) == "".
  3. If building SQL from variables, log the rendered statement before sending to catch empty substitutions.

Example fix

// before
stmt := strings.TrimSpace(userInput)
api.QuerySQL(stmt) // errors if empty
// after
stmt := strings.TrimSpace(userInput)
if stmt == "" { return errors.New("query is required") }
api.QuerySQL(stmt)
Defensive patterns

Strategy: validation

Validate before calling

// Caller side: skip empty queries before calling the SQL API.
const trimmed = stmt.trim()
if (trimmed === '') return new Error('query is required')
await api.querySQL(trimmed)

Try / catch

try { await api.querySQL(stmt) }
catch (e) {
  if (/statement is empty/i.test(String(e))) console.warn('skip empty SQL submission')
  else throw e
}

Prevention

When it happens

Trigger: Submitting an empty or whitespace-only SQL string ("", " ", "\n\t") to the SQL query API; a script passes an unset variable as the statement.

Common situations: UI submitted before typing; template/variable substitution produced empty string; CLI invoked with empty --stmt; trim of a comment-only statement yields empty.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/e11065f041786535. Report an issue: GitHub.