@@ -141,6 +141,8 @@ Postgres.prototype.visit = function(node) {
141141 case 'PREFIX UNARY' : return this . visitPrefixUnary ( node ) ;
142142 case 'BINARY' : return this . visitBinary ( node ) ;
143143 case 'TERNARY' : return this . visitTernary ( node ) ;
144+ case 'IN' : return this . visitIn ( node ) ;
145+ case 'NOT IN' : return this . visitNotIn ( node ) ;
144146 case 'CASE' : return this . visitCase ( node ) ;
145147 case 'AT' : return this . visitAt ( node ) ;
146148 case 'SLICE' : return this . visitSlice ( node ) ;
@@ -290,9 +292,9 @@ Postgres.prototype.visitFrom = function(from) {
290292} ;
291293
292294Postgres . prototype . visitWhere = function ( where ) {
293- this . _visitingWhere = true ;
295+ this . _visitingWhere = true ;
294296 var result = [ 'WHERE' , where . nodes . map ( this . visit . bind ( this ) ) . join ( ', ' ) ] ;
295- this . _visitingWhere = false ;
297+ this . _visitingWhere = false ;
296298 return result ;
297299} ;
298300
@@ -369,6 +371,81 @@ Postgres.prototype.visitTernary = function(ternary) {
369371 return [ text ] ;
370372} ;
371373
374+ Postgres . prototype . visitIn = function ( binary ) {
375+ var self = this ;
376+ var text = '(' ;
377+
378+ if ( Array . isArray ( binary . right ) ) {
379+ if ( binary . right . length ) {
380+ var params = [ ] ;
381+ var hasNull = false ;
382+
383+ binary . right . forEach ( function ( node ) {
384+ if ( node . type === 'PARAMETER' && node . _val === null ) {
385+ hasNull = true ;
386+ } else {
387+ params . push ( self . visit ( node ) ) ;
388+ }
389+ } ) ;
390+
391+ if ( params . length ) {
392+ text += this . visit ( binary . left ) + ' IN (' + params . join ( ', ' ) + ')' ;
393+
394+ if ( hasNull ) {
395+ text += ' OR ' + this . visit ( binary . left ) + ' IS NULL' ;
396+ }
397+ } else { // implicitely has null
398+ text += this . visit ( binary . left ) + ' IS NULL' ;
399+ }
400+ } else {
401+ text += '1=0' ;
402+ }
403+ } else {
404+ text += this . visit ( binary . left ) + ' IN ' + this . visit ( binary . right ) ;
405+ }
406+
407+ text += ')' ;
408+ return [ text ] ;
409+ } ;
410+
411+ Postgres . prototype . visitNotIn = function ( binary ) {
412+ var self = this ;
413+ var text = '(' ;
414+
415+ if ( Array . isArray ( binary . right ) ) {
416+ if ( binary . right . length ) {
417+ var params = [ ] ;
418+ var hasNull = false ;
419+
420+ binary . right . forEach ( function ( node ) {
421+ if ( node . type === 'PARAMETER' && node . _val === null ) {
422+ hasNull = true ;
423+ } else {
424+ params . push ( self . visit ( node ) ) ;
425+ }
426+ } ) ;
427+
428+ if ( params . length && hasNull ) {
429+ text += 'NOT (' ;
430+ text += this . visit ( binary . left ) + ' IN (' + params . join ( ', ' ) + ')' ;
431+ text += ' OR ' + this . visit ( binary . left ) + ' IS NULL' ;
432+ text += ')' ;
433+ } else if ( params . length ) {
434+ text += this . visit ( binary . left ) + ' NOT IN (' + params . join ( ', ' ) + ')' ;
435+ } else { // implicitely has null
436+ text += this . visit ( binary . left ) + ' IS NOT NULL' ;
437+ }
438+ } else {
439+ text += '1=1' ;
440+ }
441+ } else {
442+ text += this . visit ( binary . left ) + ' NOT IN ' + this . visit ( binary . right ) ;
443+ }
444+
445+ text += ')' ;
446+ return [ text ] ;
447+ } ;
448+
372449Postgres . prototype . visitCase = function ( caseExp ) {
373450 assert ( caseExp . whenList . length == caseExp . thenList . length ) ;
374451
@@ -542,7 +619,7 @@ Postgres.prototype.visitColumn = function(columnNode) {
542619 var col = table . columns [ i ] ;
543620 var aliased = col . name !== ( col . alias || col . property ) ;
544621 hasAliases = hasAliases || aliased ;
545- allCols . push ( this . quote ( col . name ) + ( aliased ? ' AS ' + this . quote ( col . alias || col . property ) : '' ) ) ;
622+ allCols . push ( this . quote ( col . name ) + ( aliased ? ' AS ' + this . quote ( col . alias || col . property ) : '' ) ) ;
546623 }
547624 txt . push ( hasAliases ? allCols . join ( ', ' ) : '*' ) ;
548625 }
0 commit comments