@@ -98,6 +98,7 @@ struct StmtTypeChecker {
9898 let result = action ( & inferrer)
9999 diagnostics = inferrer. diagnostics
100100 nameInferrer = inferrer. nameInferrer
101+ inferenceState = inferrer. inferenceState
101102 return result
102103 }
103104}
@@ -239,16 +240,11 @@ extension StmtTypeChecker {
239240 typeCheck ( cte: cte)
240241 }
241242
242- let resultColumns = switch select. selects. value {
243- case let . single( selectCore) :
244- typeCheck (
245- select: selectCore,
246- at: select. location,
247- potentialNames: potentialNames
248- )
249- case . compound:
250- fatalError ( )
251- }
243+ let resultColumns = typeCheck (
244+ selects: select. selects. value,
245+ at: select. location,
246+ potentialNames: potentialNames
247+ )
252248
253249 for term in select. orderBy {
254250 _ = typeCheck ( term. expr)
@@ -261,6 +257,54 @@ extension StmtTypeChecker {
261257 return resultColumns
262258 }
263259
260+ mutating func typeCheck(
261+ selects: SelectStmtSyntax . Selects ,
262+ at location: SourceLocation ,
263+ potentialNames: [ IdentifierSyntax ] ? = nil
264+ ) -> ResultColumns {
265+ switch selects {
266+ case let . single( selectCore) :
267+ return typeCheck (
268+ select: selectCore,
269+ at: location,
270+ potentialNames: potentialNames
271+ )
272+ case let . compound( first, op, second) :
273+ // SQLite:
274+ // * Does not care about types
275+ // * Uses names of first
276+ // * Cares about # of columns
277+
278+ let firstResult = inNewEnvironment { typeChecker in
279+ typeChecker. typeCheck (
280+ select: first,
281+ at: location,
282+ potentialNames: potentialNames
283+ )
284+ }
285+
286+ let secondResult = inNewEnvironment { typeChecker in
287+ typeChecker. typeCheck ( selects: second, at: location)
288+ }
289+
290+ guard firstResult. count == secondResult. count else {
291+ diagnostics. add ( . init(
292+ " SELECTs for \( op. kind) do not have the same number of columns ( \( firstResult. count) and \( secondResult. count) ) " ,
293+ at: op. location
294+ ) )
295+ return firstResult
296+ }
297+
298+ var index = 0
299+ let secondColumns = secondResult. allColumns. values
300+ return firstResult. mapTypes { type in
301+ inferenceState. unify ( type, with: secondColumns [ index] , at: location)
302+ index += 1
303+ return type
304+ }
305+ }
306+ }
307+
264308 mutating func typeCheck( insert: InsertStmtSyntax ) -> ResultColumns {
265309 if let cte = insert. cte {
266310 typeCheck ( cte: cte)
@@ -579,6 +623,7 @@ extension StmtTypeChecker {
579623
580624 if let name = alias? . identifier. value ?? names. proposedName {
581625 columns [ name] = type
626+ nameInferrer. suggest ( name: name, for: names)
582627 } else {
583628 diagnostics. add ( . nameRequired( at: expr. location) )
584629 }
0 commit comments