INSERT with named columns for a table with generated columns.

FossilOrigin-Name: 64db39f92d68d1b9f23e48af35e16b969c38b58041fbe900066eeb3ddb291cef
diff --git a/src/expr.c b/src/expr.c
index e02e146..c21006b 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -3381,6 +3381,7 @@
   int regOut      /* Extract the value into this register */
 ){
   Vdbe *v = pParse->pVdbe;
+  Column *pCol;
   assert( v!=0 );
   if( pTab==0 ){
     sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
@@ -3395,11 +3396,17 @@
       op = OP_VColumn;
       x = iCol;
 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
-    }else if( pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL ){
-      int savedSelfTab = pParse->iSelfTab;
-      pParse->iSelfTab = iTabCur+1;
-      sqlite3ExprCode(pParse, pTab->aCol[iCol].pDflt, regOut);
-      pParse->iSelfTab = savedSelfTab;
+    }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){
+      if( pCol->colFlags & COLFLAG_BUSY ){
+        sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName);
+      }else{
+        int savedSelfTab = pParse->iSelfTab;
+        pCol->colFlags |= COLFLAG_BUSY;
+        pParse->iSelfTab = iTabCur+1;
+        sqlite3ExprCode(pParse, pTab->aCol[iCol].pDflt, regOut);
+        pParse->iSelfTab = savedSelfTab;
+        pCol->colFlags &= ~COLFLAG_BUSY;
+      }
       return;
 #endif
     }else if( !HasRowid(pTab) ){