@@ -93,3 +93,45 @@ Ensure postgres is installed, then run:
93
93
94
94
NB at the time of writing, this script predates the split into separate ` state ` /` main `
95
95
databases so will require updates to handle that correctly.
96
+
97
+ ## Boolean columns
98
+
99
+ Boolean columns require special treatment, since SQLite treats booleans the
100
+ same as integers.
101
+
102
+ There are three separate aspects to this:
103
+
104
+ * Any new boolean column must be added to the ` BOOLEAN_COLUMNS ` list in
105
+ ` scripts/synapse_port_db ` . This tells the port script to cast the integer
106
+ value from SQLite to a boolean before writing the value to the postgres
107
+ database.
108
+
109
+ * Before SQLite 3.23, ` TRUE ` and ` FALSE ` were not recognised as constants by
110
+ SQLite, and the ` IS [NOT] TRUE ` /` IS [NOT] FALSE ` operators were not
111
+ supported. This makes it necessary to avoid using ` TRUE ` and ` FALSE `
112
+ constants in SQL commands.
113
+
114
+ For example, to insert a ` TRUE ` value into the database, write:
115
+
116
+ ``` python
117
+ txn.execute(" INSERT INTO tbl(col) VALUES (?)" , (True , ))
118
+ ```
119
+
120
+ * Default values for new boolean columns present a particular
121
+ difficulty. Generally it is best to create separate schema files for
122
+ Postgres and SQLite. For example:
123
+
124
+ ``` sql
125
+ # in 00delta.sql.postgres:
126
+ ALTER TABLE tbl ADD COLUMN col BOOLEAN DEFAULT FALSE;
127
+ ```
128
+
129
+ ``` sql
130
+ # in 00delta.sql.sqlite:
131
+ ALTER TABLE tbl ADD COLUMN col BOOLEAN DEFAULT 0 ;
132
+ ```
133
+
134
+ Note that there is a particularly insidious failure mode here: the Postgres
135
+ flavour will be accepted by SQLite 3.22, but will give a column whose
136
+ default value is the ** string** ` "FALSE" ` - which, when cast back to a boolean
137
+ in Python, evaluates to ` True ` .
0 commit comments