@@ -107,7 +107,7 @@ class ClickhouseConnector extends AdminForthBaseConnector implements IAdminForth
107107 }
108108 return dayjs ( value ) . toISOString ( ) . split ( 'T' ) [ 0 ] ;
109109 } else if ( field . type == AdminForthDataTypes . BOOLEAN ) {
110- return ! ! value ;
110+ return value === null ? null : ! ! value ;
111111 } else if ( field . type == AdminForthDataTypes . JSON ) {
112112 if ( field . _underlineType . startsWith ( 'String' ) || field . _underlineType . startsWith ( 'FixedString' ) ) {
113113 try {
@@ -138,7 +138,7 @@ class ClickhouseConnector extends AdminForthBaseConnector implements IAdminForth
138138 return iso ;
139139 }
140140 } else if ( field . type == AdminForthDataTypes . BOOLEAN ) {
141- return value ? 1 : 0 ;
141+ return value === null ? null : ( value ? 1 : 0 ) ;
142142 } else if ( field . type == AdminForthDataTypes . JSON ) {
143143 // check underline type is text or string
144144 if ( field . _underlineType . startsWith ( 'String' ) || field . _underlineType . startsWith ( 'FixedString' ) ) {
@@ -180,6 +180,19 @@ class ClickhouseConnector extends AdminForthBaseConnector implements IAdminForth
180180 let operator = this . OperatorsMap [ filter . operator ] ;
181181 if ( filter . operator == AdminForthFilterOperators . IN || filter . operator == AdminForthFilterOperators . NIN ) {
182182 placeholder = `(${ filter . value . map ( ( _ , j ) => `{p$?:${ column . _underlineType } }` ) . join ( ', ' ) } )` ;
183+ } else if ( filter . operator == AdminForthFilterOperators . EQ && filter . value === null ) {
184+ operator = 'IS' ;
185+ placeholder = 'NULL' ;
186+ } else if ( filter . operator == AdminForthFilterOperators . NE ) {
187+ if ( filter . value === null ) {
188+ operator = 'IS NOT' ;
189+ placeholder = 'NULL' ;
190+ } else {
191+ // for not equal, we need to add a null check
192+ // because nullish field will not match != value
193+ placeholder = `${ placeholder } OR ${ field } IS NULL)` ;
194+ field = `(${ field } ` ;
195+ }
183196 }
184197
185198 return `${ field } ${ operator } ${ placeholder } ` ;
@@ -209,6 +222,12 @@ class ClickhouseConnector extends AdminForthBaseConnector implements IAdminForth
209222 return [ { 'f' : `%${ filter . value } %` } ] ;
210223 } else if ( filter . operator == AdminForthFilterOperators . IN || filter . operator == AdminForthFilterOperators . NIN ) {
211224 return [ { 'p' : filter . value } ] ;
225+ } else if ( filter . operator == AdminForthFilterOperators . EQ && filter . value === null ) {
226+ // there is no param for IS NULL filter
227+ return [ ] ;
228+ } else if ( filter . operator == AdminForthFilterOperators . NE && filter . value === null ) {
229+ // there is no param for IS NOT NULL filter
230+ return [ ] ;
212231 } else {
213232 return [ { 'f' : ( filter as IAdminForthSingleFilter ) . value } ] ;
214233 }
0 commit comments