@@ -132,7 +132,11 @@ func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, er
132
132
if res .Name != nil {
133
133
name = * res .Name
134
134
}
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 )
136
140
137
141
case * ast.A_Expr :
138
142
name := ""
@@ -164,50 +168,67 @@ func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, er
164
168
cols = append (cols , & Column {Name : name , DataType : "bool" , NotNull : notNull })
165
169
166
170
case * ast.CaseExpr :
167
- name := ""
171
+ var name string
168
172
if res .Name != nil {
169
173
name = * res .Name
170
174
}
171
175
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 := ""
183
177
chosenNullable := false
178
+
184
179
for _ , i := range n .Args .Items {
185
180
cw := i .(* ast.CaseWhen )
186
- col , err := convertCaseExprCondToColumn (cw .Result , res . Name )
181
+ col , err := convertCaseExprCondToColumn (cw .Result , & name )
187
182
if err != nil {
188
183
return nil , err
189
184
}
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
+ }
192
196
}
193
197
if ! col .NotNull {
194
198
chosenNullable = true
195
199
}
196
200
}
197
201
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 )
200
205
if err != nil {
201
206
return nil , err
202
207
}
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
+ }
205
222
}
206
223
if ! defaultCol .NotNull {
207
224
chosenNullable = true
208
225
}
209
226
}
210
227
228
+ if chosenType == "" {
229
+ chosenType = "any"
230
+ }
231
+
211
232
chosenColumn := & Column {Name : name , DataType : chosenType , NotNull : ! chosenNullable }
212
233
cols = append (cols , chosenColumn )
213
234
@@ -811,7 +832,7 @@ func convertAExprToColumn(aexpr *ast.A_Expr, name string) *Column {
811
832
return col
812
833
}
813
834
814
- func convertAConstToColumn (aconst * ast.A_Const , name string ) * Column {
835
+ func convertAConstToColumn (aconst * ast.A_Const , name string ) ( * Column ) {
815
836
var col * Column
816
837
switch aconst .Val .(type ) {
817
838
case * ast.String :
@@ -822,6 +843,8 @@ func convertAConstToColumn(aconst *ast.A_Const, name string) *Column {
822
843
col = & Column {Name : name , DataType : "float" , NotNull : true }
823
844
case * ast.Boolean :
824
845
col = & Column {Name : name , DataType : "bool" , NotNull : true }
846
+ case * ast.Null :
847
+ col = & Column {Name : name , DataType : "null" , NotNull : false }
825
848
default :
826
849
col = & Column {Name : name , DataType : "any" , NotNull : false }
827
850
}
0 commit comments