"""Original NULL predicate fixture; SQLite in memory only, no app DB."""
import sqlite3,json
def demo():
    c=sqlite3.connect(':memory:');c.execute('CREATE TABLE item(id INTEGER PRIMARY KEY, x INTEGER)');c.executemany('INSERT INTO item VALUES(?,?)',[(1,0),(2,2),(3,None)]);c.execute('CREATE TABLE rhs(x INTEGER)');c.executemany('INSERT INTO rhs VALUES(?)',[(2,),(None,)])
    def ids(where):return [x[0]for x in c.execute('SELECT id FROM item AS a WHERE '+where+' ORDER BY id')]
    q={'equals_null':ids('x = NULL'),'is_null':ids('x IS NULL'),'not_in_rhs_with_null':ids('x NOT IN(SELECT x FROM rhs)'),'not_in_rhs_no_null':ids('x NOT IN(SELECT x FROM rhs WHERE x IS NOT NULL)'),'not_in_empty_rhs':ids('x NOT IN(SELECT x FROM rhs WHERE 0)'),'not_exists_equality':ids('NOT EXISTS(SELECT 1 FROM rhs AS b WHERE b.x=a.x)'),'not_exists_exclude_left_null':ids('a.x IS NOT NULL AND NOT EXISTS(SELECT 1 FROM rhs AS b WHERE b.x=a.x)')}
    assert q=={'equals_null':[],'is_null':[3],'not_in_rhs_with_null':[],'not_in_rhs_no_null':[1],'not_in_empty_rhs':[1,2,3],'not_exists_equality':[1,3],'not_exists_exclude_left_null':[1]}
    truth=[list(r)for r in c.execute('SELECT id,x,x=NULL,x IS NULL,x IN(SELECT x FROM rhs),x NOT IN(SELECT x FROM rhs) FROM item ORDER BY id')];counts=list(c.execute('SELECT COUNT(*),COUNT(x),SUM(x) FROM item').fetchone());assert counts==[3,2,2]
    c.close();return {'sqlite_version':sqlite3.sqlite_version,'authored_item_rows':[[1,0],[2,2],[3,None]],'authored_rhs':[2,None],'truth_columns':['id','x','x_equal_null','x_is_null','x_in_rhs','x_not_in_rhs'],'truth':truth,'where_results':q,'count_star_count_x_sum_x':counts,'left_null_policy':'NOT EXISTS with equality includes NULL left because no equality match is true; exclude it explicitly if required. Empty RHS makes NOT IN true even for NULL in SQLite. Not a universal equivalence claim or imputation.','network_or_app_database_accessed':False}
if __name__=='__main__':print(json.dumps(demo(),indent=2))
