@@ -439,7 +439,7 @@ extension StmtTypeChecker: StmtSyntaxVisitor {
439439extension StmtTypeChecker {
440440 mutating func typeCheck(
441441 select: SelectStmtSyntax ,
442- potentialNames: [ IdentifierSyntax ] ? = nil
442+ potentialNames: [ Substring ] ? = nil
443443 ) -> ResultColumns {
444444 typeCheck ( with: select. with)
445445
@@ -483,7 +483,7 @@ extension StmtTypeChecker {
483483 mutating func typeCheck(
484484 selects: SelectStmtSyntax . Selects ,
485485 at location: SourceLocation ,
486- potentialNames: [ IdentifierSyntax ] ? = nil
486+ potentialNames: [ Substring ] ? = nil
487487 ) -> ResultColumns {
488488 switch selects {
489489 case let . single( selectCore) :
@@ -545,26 +545,55 @@ extension StmtTypeChecker {
545545
546546 usedTableNames. insert ( table. name. name)
547547
548+ // If there is an error upstream that will cause unification to fail for sure
549+ // we can just skip it so the real error does not get hidden by all the other errors
550+ var skipInputUnification = false
551+ let columNames : [ Substring ]
548552 let inputType : Type
549553 if let columns = insert. columns {
550554 var columnTypes : [ Type ] = [ ]
555+ var setColumns : Set < Substring > = [ ]
551556 for column in columns {
552557 guard let def = table. columns [ column. value] . first else {
553558 diagnostics. add ( . columnDoesNotExist( column) )
554559 columnTypes. append ( . error)
555560 continue
556561 }
557562
563+ if def. isGenerated {
564+ diagnostics. add ( . init( " Column is generated and not able to be set " , at: column. location) )
565+ }
566+
558567 columnTypes. append ( def. type)
568+ setColumns. insert ( column. value)
569+ }
570+
571+ let requiredColumns = Set ( table. requiredColumnsNames)
572+ let missingColumns = requiredColumns. subtracting ( setColumns)
573+
574+ if !missingColumns. isEmpty {
575+ let names = missingColumns. map { " ' \( $0) ' " } . joined ( separator: " , " )
576+ diagnostics. add ( . init( " Missing required columns \( names) " , at: insert. location) )
577+ // Skip unification since it will fail for sure, and this diag is more specific
578+ // to their issue.
579+ skipInputUnification = true
559580 }
581+
560582 inputType = . row( . fixed( columnTypes) )
583+ columNames = columns. map ( \. value)
561584 } else {
562- inputType = table. type
585+ let columns = table. nonGeneratedColumns
586+ inputType = . row( . fixed( columns. map ( \. 1 . type) ) )
587+ columNames = columns. map ( \. 0 )
563588 }
564589
565590 if let values = insert. values {
566- let resultColumns = typeCheck ( select: values. select, potentialNames: insert. columns)
567- inferenceState. unify ( inputType, with: resultColumns. type, at: insert. location)
591+ let resultColumns = typeCheck ( select: values. select, potentialNames: columNames)
592+
593+ // Unify the input columns with the actual input values
594+ if !skipInputUnification {
595+ inferenceState. unify ( inputType, with: resultColumns. type, at: insert. location)
596+ }
568597 } else {
569598 // TODO: Using 'DEFALUT VALUES' make sure all columns
570599 // TODO: actually have default values or null
@@ -770,7 +799,7 @@ extension StmtTypeChecker {
770799 private mutating func typeCheck(
771800 select: SelectCoreSyntax ,
772801 at range: SourceLocation ,
773- potentialNames: [ IdentifierSyntax ] ? = nil
802+ potentialNames: [ Substring ] ? = nil
774803 ) -> ResultColumns {
775804 switch select {
776805 case let . select( select) :
@@ -788,7 +817,7 @@ extension StmtTypeChecker {
788817 // If there are potential names to match with check to
789818 // see if there is one at the index of this expression.
790819 if let potentialNames, index < potentialNames. count {
791- nameInferrer. suggest ( name: potentialNames [ index] . value , for: name)
820+ nameInferrer. suggest ( name: potentialNames [ index] , for: name)
792821 }
793822 }
794823
0 commit comments