--- title: "SQLite: IS NOT NULL AS Boolean" aliases: [sqlite-not-null-boolean, sqlite-derived-boolean] tags: [sqlite, sql, security, pattern] sources: [sandbox] created: 2026-05-05 updated: 2026-05-05 --- # SQLite: IS NOT NULL AS Boolean When a column contains sensitive data (e.g. a password hash), never select it directly to answer a yes/no question. Use `(column IS NOT NULL) AS flag` to return a derived boolean instead. ## Key Takeaways - `(password_hash IS NOT NULL) AS has_password` → returns `1` or `0`, never the hash - Hash never leaves the database layer — client gets the correct boolean - Standard pattern for any column that must stay server-side ## Pattern ```sql -- BAD: leaks the hash to the application layer SELECT id, email, password_hash FROM users WHERE id = ?; -- GOOD: returns a boolean, hash stays in DB SELECT id, email, (password_hash IS NOT NULL) AS has_password FROM users WHERE id = ?; ``` In SQLite, the expression evaluates to `1` (true) or `0` (false). Map to a JS/Python boolean at the application layer: ```js // Node.js / better-sqlite3 const user = db.prepare(` SELECT id, email, (password_hash IS NOT NULL) AS has_password FROM users WHERE id = ? `).get(userId); // SQLite returns 1/0; coerce to boolean user.hasPassword = Boolean(user.has_password); ``` ## Bug This Fixes The `userPublic()` helper was selecting `u.password_hash` directly. The result object included the raw hash — or, worse, `undefined` when the column was NULL — causing `hasPassword` to always evaluate to `false` (because the hash value was truthy but the field name wasn't mapped correctly). Fix: replace the direct column with `(password_hash IS NOT NULL) AS has_password`. ## Generalisation The same pattern applies to any secret or large binary: - `(api_key IS NOT NULL) AS has_api_key` - `(avatar_blob IS NOT NULL) AS has_avatar` - `(refresh_token IS NOT NULL) AS is_linked` ## Related - [[wiki/concepts/fastapi-response-model-silent-field-strip|fastapi-response-model-silent-field-strip]] — similar idea: strip sensitive fields at the serialization layer