@@ -132,7 +132,11 @@ func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, er
132132 if res .Name != nil {
133133 name = * res .Name
134134 }
135- cols = append (cols , convertAConstToColumn (n , name ))
135+ col := convertAConstToColumn (n , name )
136+ if col .DataType == "null" {
137+ col .DataType = "any"
138+ }
139+ cols = append (cols , col )
136140
137141 case * ast.A_Expr :
138142 name := ""
@@ -164,50 +168,67 @@ func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, er
164168 cols = append (cols , & Column {Name : name , DataType : "bool" , NotNull : notNull })
165169
166170 case * ast.CaseExpr :
167- name := ""
171+ var name string
168172 if res .Name != nil {
169173 name = * res .Name
170174 }
171175
172- typePrecedence := map [string ]int {
173- "any" : 0 ,
174- "bool" : 1 ,
175- "int" : 2 ,
176- "pg_catalog.int4" : 2 ,
177- "float" : 3 ,
178- "pg_catalog.float8" : 3 ,
179- "text" : 4 ,
180- }
181-
182- chosenType := "any"
176+ chosenType := ""
183177 chosenNullable := false
178+
184179 for _ , i := range n .Args .Items {
185180 cw := i .(* ast.CaseWhen )
186- col , err := convertCaseExprCondToColumn (cw .Result , res . Name )
181+ col , err := convertCaseExprCondToColumn (cw .Result , & name )
187182 if err != nil {
188183 return nil , err
189184 }
190- if typePrecedence [col .DataType ] > typePrecedence [chosenType ] {
191- chosenType = col .DataType
185+ if col .DataType == "null" {
186+ // we don't choose type from this column if its value is null, only choose nullability
187+ chosenNullable = true
188+ continue
189+ }
190+ if col .DataType != chosenType {
191+ if chosenType == "" {
192+ chosenType = col .DataType
193+ } else {
194+ chosenType = "any"
195+ }
192196 }
193197 if ! col .NotNull {
194198 chosenNullable = true
195199 }
196200 }
197201
198- if n .Defresult != nil {
199- defaultCol , err := convertCaseExprCondToColumn (n .Defresult , res .Name )
202+ var defaultCol * Column
203+ if n .Defresult .Pos () != 0 {
204+ defaultCol , err = convertCaseExprCondToColumn (n .Defresult , & name )
200205 if err != nil {
201206 return nil , err
202207 }
203- if typePrecedence [defaultCol .DataType ] > typePrecedence [chosenType ] {
204- chosenType = defaultCol .DataType
208+ } else {
209+ defaultCol = & Column {Name : name , DataType : "null" , NotNull : false }
210+ }
211+
212+ if defaultCol .DataType == "null" {
213+ // we don't choose type from this column if its value is null, only choose nullability
214+ chosenNullable = true
215+ } else {
216+ if defaultCol .DataType != chosenType {
217+ if chosenType == "" {
218+ chosenType = defaultCol .DataType
219+ } else {
220+ chosenType = "any"
221+ }
205222 }
206223 if ! defaultCol .NotNull {
207224 chosenNullable = true
208225 }
209226 }
210227
228+ if chosenType == "" {
229+ chosenType = "any"
230+ }
231+
211232 chosenColumn := & Column {Name : name , DataType : chosenType , NotNull : ! chosenNullable }
212233 cols = append (cols , chosenColumn )
213234
@@ -811,7 +832,7 @@ func convertAExprToColumn(aexpr *ast.A_Expr, name string) *Column {
811832 return col
812833}
813834
814- func convertAConstToColumn (aconst * ast.A_Const , name string ) * Column {
835+ func convertAConstToColumn (aconst * ast.A_Const , name string ) ( * Column ) {
815836 var col * Column
816837 switch aconst .Val .(type ) {
817838 case * ast.String :
@@ -822,6 +843,8 @@ func convertAConstToColumn(aconst *ast.A_Const, name string) *Column {
822843 col = & Column {Name : name , DataType : "float" , NotNull : true }
823844 case * ast.Boolean :
824845 col = & Column {Name : name , DataType : "bool" , NotNull : true }
846+ case * ast.Null :
847+ col = & Column {Name : name , DataType : "null" , NotNull : false }
825848 default :
826849 col = & Column {Name : name , DataType : "any" , NotNull : false }
827850 }
0 commit comments