@@ -516,7 +516,11 @@ extension StmtTypeChecker {
516516 var index = 0
517517 let secondColumns = secondResult. allColumns. values
518518 return firstResult. mapTypes { type in
519- inferenceState. unify ( type, with: secondColumns [ index] , at: location)
519+ inferenceState. unify (
520+ type,
521+ with: inferenceState. solution ( for: secondColumns [ index] ) ,
522+ at: location
523+ )
520524 index += 1
521525 return type
522526 }
@@ -691,20 +695,36 @@ extension StmtTypeChecker {
691695
692696 for cte in with. ctes {
693697 let table = inNewEnvironment { typeChecker in
694- typeChecker. typeCheck ( cte: cte)
698+ typeChecker. typeCheck ( cte: cte, recursive : with . recursive )
695699 }
696700
697701 ctes [ cte. table. value] = table
698702 }
699703 }
700704
701- private mutating func typeCheck( cte: CommonTableExpressionSyntax ) -> Table {
702- let resultColumns = typeCheck ( select: cte. select)
703-
704- let columns : Columns
705+ private mutating func typeCheck(
706+ cte: CommonTableExpressionSyntax ,
707+ recursive: Bool
708+ ) -> Table {
709+ let cteName = QualifiedName ( name: cte. table. value, schema: nil )
710+
705711 if cte. columns. isEmpty {
706- columns = resultColumns. allColumns
712+ let resultColumns = typeCheck ( select: cte. select)
713+ return Table ( name: cteName, columns: resultColumns. allColumns, kind: . cte)
707714 } else {
715+ // CTE's can reference themselves so we need to create a table to
716+ // represent this CTE with all columns as type variables.
717+ let thisCte = Table (
718+ name: cteName,
719+ columns: cte. columns. reduce ( into: [ : ] ) { columns, name in
720+ columns. append ( inferenceState. freshTyVar ( for: name) , for: name. value)
721+ } ,
722+ kind: . cte
723+ )
724+
725+ ctes [ thisCte. name. name] = thisCte
726+
727+ let resultColumns = typeCheck ( select: cte. select)
708728 let columnTypes = resultColumns. allColumns. values
709729 if columnTypes. count != cte. columns. count {
710730 diagnostics. add ( . init(
@@ -713,16 +733,10 @@ extension StmtTypeChecker {
713733 ) )
714734 }
715735
716- columns = ( 0 ..< min ( columnTypes. count, cte. columns. count) )
717- . reduce ( into: [ : ] ) { $0. append ( columnTypes [ $1] , for: cte. columns [ $1] . value) }
736+ // Simply return the table but getting the solution types so the substitution
737+ // map retains it's integrity.
738+ return thisCte. mapTypes { inferenceState. solution ( for: $0) }
718739 }
719-
720- return Table (
721- name: QualifiedName ( name: cte. table. value, schema: nil ) ,
722- columns: columns,
723- primaryKey: [ ] ,
724- kind: . cte
725- )
726740 }
727741
728742 /// Will infer the core part of the select.
0 commit comments