private void FindDependencies(Component instruction, ref Schema schema) { var dependencies = instruction.Dependencies; foreach (var dependency in dependencies) { var componentTo = FindComponent(dependency); schema.Components.Add(componentTo.Name); schema.AddConnection(instruction.Name, dependency, componentTo.Name); FindDependencies(componentTo, ref schema); } }
public static void SimpleResolved(Component instruction, ref Schema schema) { var dependencies = instruction.Dependencies; foreach (var dependency in dependencies) { var componentTo = FindComponent(dependency); schema.Components.Add(componentTo.Name); schema.AddConnection(instruction.Name, dependency, componentTo.Name); SimpleResolved(componentTo, ref schema); } }
public Schema GenerateSchema(string instructionName) { var instruction = _db.Instructions.FirstOrDefault(i => i.Name == instructionName); if (instruction == null) { throw new Exception("нет такой инструкции"); } var schema = new Schema(); //ResolvedAlgorithm.SimpleResolved(instruction, ref schema); FindDependencies(instruction, ref schema); return schema; }
static bool sqlite3SchemaMutexHeld(object X, int y, Schema z) { return true; }
static WRC LookupName(Parse parse, string dbName, string tableName, string colName, NameContext nc, Expr expr) { int cnt = 0; // Number of matching column names int cntTab = 0; // Number of matching table names int subquerys = 0; // How many levels of subquery Context ctx = parse.Ctx; // The database connection SrcList.SrcListItem item; // Use for looping over pSrcList items SrcList.SrcListItem match = null; // The matching pSrcList item NameContext topNC = nc; // First namecontext in the list Schema schema = null; // Schema of the expression bool isTrigger = false; int i, j; Debug.Assert(nc != null); // the name context cannot be NULL. Debug.Assert(colName != null); // The Z in X.Y.Z cannot be NULL Debug.Assert(!E.ExprHasAnyProperty(expr, EP.TokenOnly | EP.Reduced)); // Initialize the node to no-match expr.TableId = -1; expr.Table = null; E.ExprSetIrreducible(expr); // Translate the schema name in zDb into a pointer to the corresponding schema. If not found, pSchema will remain NULL and nothing will match // resulting in an appropriate error message toward the end of this routine if (dbName != null) { for (i = 0; i < ctx.DBs.length; i++) { Debug.Assert(ctx.DBs[i].Name != null); if (string.Compare(ctx.DBs[i].Name, dbName) == 0) { schema = ctx.DBs[i].Schema; break; } } } // Start at the inner-most context and move outward until a match is found while (nc != null && cnt == 0) { ExprList list; SrcList srcList = nc.SrcList; if (srcList != null) { for (i = 0; i < srcList.Srcs; i++) { item = srcList.Ids[i]; Table table = item.Table; Debug.Assert(table != null && table.Name != null); Debug.Assert(table.Cols.length > 0); if (item.Select != null && (item.Select.SelFlags & SF.NestedFrom) != 0) { bool hit = false; list = item.Select.EList; for (j = 0; j < list.Exprs; j++) { if (Walker.MatchSpanName(list.Ids[j].Span, colName, tableName, dbName)) { cnt++; cntTab = 2; match = item; expr.ColumnId = j; hit = true; } } if (hit || table == null) { continue; } } if (dbName != null && table.Schema != schema) { continue; } if (tableName != null) { string tableName2 = (item.Alias != null ? item.Alias : table.Name); Debug.Assert(tableName2 != null); if (!string.Equals(tableName2, tableName, StringComparison.OrdinalIgnoreCase)) { continue; } } if (cntTab++ == 0) { match = item; } Column col; for (j = 0; j < table.Cols.length; j++) { col = table.Cols[j]; if (string.Equals(col.Name, colName, StringComparison.InvariantCultureIgnoreCase)) { // If there has been exactly one prior match and this match is for the right-hand table of a NATURAL JOIN or is in a // USING clause, then skip this match. if (cnt == 1) { if ((item.Jointype & JT.NATURAL) != 0) { continue; } if (NameInUsingClause(item.Using, colName)) { continue; } } cnt++; match = item; // Substitute the rowid (column -1) for the INTEGER PRIMARY KEY expr.ColumnId = (j == table.PKey ? -1 : (short)j); break; } } } if (match != null) { expr.TableId = match.Cursor; expr.Table = match.Table; schema = expr.Table.Schema; } } #if !OMIT_TRIGGER // If we have not already resolved the name, then maybe it is a new.* or old.* trigger argument reference if (dbName == null && tableName != null && cnt == 0 && parse.TriggerTab != null) { TK op = parse.TriggerOp; Table table = null; Debug.Assert(op == TK.DELETE || op == TK.UPDATE || op == TK.INSERT); if (op != TK.DELETE && string.Equals("new", tableName, StringComparison.InvariantCultureIgnoreCase)) { expr.TableId = 1; table = parse.TriggerTab; } else if (op != TK.INSERT && string.Equals("old", tableName, StringComparison.InvariantCultureIgnoreCase)) { expr.TableId = 0; table = parse.TriggerTab; } if (table != null) { int colId; schema = table.Schema; cntTab++; for (colId = 0; colId < table.Cols.length; colId++) { Column col = table.Cols[colId]; if (string.Equals(col.Name, colName, StringComparison.InvariantCultureIgnoreCase)) { if (colId == table.PKey) { colId = -1; } break; } } if (colId >= table.Cols.length && Expr.IsRowid(colName)) { colId = -1; // IMP: R-44911-55124 } if (colId < table.Cols.length) { cnt++; if (colId < 0) { expr.Aff = AFF.INTEGER; } else if (expr.TableId == 0) { C.ASSERTCOVERAGE(colId == 31); C.ASSERTCOVERAGE(colId == 32); parse.Oldmask |= (colId >= 32 ? 0xffffffff : (((uint)1) << colId)); } else { C.ASSERTCOVERAGE(colId == 31); C.ASSERTCOVERAGE(colId == 32); parse.Newmask |= (colId >= 32 ? 0xffffffff : (((uint)1) << colId)); } expr.ColumnId = (short)colId; expr.Table = table; isTrigger = true; } } } #endif // Perhaps the name is a reference to the ROWID if (cnt == 0 && cntTab == 1 && Expr.IsRowid(colName)) { cnt = 1; expr.ColumnId = -1; // IMP: R-44911-55124 expr.Aff = AFF.INTEGER; } // If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z might refer to an result-set alias. This happens, for example, when // we are resolving names in the WHERE clause of the following command: // // SELECT a+b AS x FROM table WHERE x<10; // // In cases like this, replace pExpr with a copy of the expression that forms the result set entry ("a+b" in the example) and return immediately. // Note that the expression in the result set should have already been resolved by the time the WHERE clause is resolved. if (cnt == 0 && (list = nc.EList) != null && tableName == null) { for (j = 0; j < list.Exprs; j++) { string asName = list.Ids[j].Name; if (asName != null && string.Equals(asName, colName, StringComparison.InvariantCultureIgnoreCase)) { Debug.Assert(expr.Left == null && expr.Right == null); Debug.Assert(expr.x.List == null); Debug.Assert(expr.x.Select == null); Expr orig = list.Ids[j].Expr; if ((nc.NCFlags & NC.AllowAgg) == 0 && E.ExprHasProperty(orig, EP.Agg)) { parse.ErrorMsg("misuse of aliased aggregate %s", asName); return(WRC.Abort); } ResolveAlias(parse, list, j, expr, "", subquerys); cnt = 1; match = null; Debug.Assert(tableName == null && dbName == null); goto lookupname_end; } } } // Advance to the next name context. The loop will exit when either we have a match (cnt>0) or when we run out of name contexts. if (cnt == 0) { nc = nc.Next; subquerys++; } } // If X and Y are NULL (in other words if only the column name Z is supplied) and the value of Z is enclosed in double-quotes, then // Z is a string literal if it doesn't match any column names. In that case, we need to return right away and not make any changes to // pExpr. // // Because no reference was made to outer contexts, the pNC->nRef fields are not changed in any context. if (cnt == 0 && tableName == null && E.ExprHasProperty(expr, EP.DblQuoted)) { expr.OP = TK.STRING; expr.Table = null; return(WRC.Prune); } // cnt==0 means there was not match. cnt>1 means there were two or more matches. Either way, we have an error. if (cnt != 1) { string err = (cnt == 0 ? "no such column" : "ambiguous column name"); if (dbName != null) { parse.ErrorMsg("%s: %s.%s.%s", err, dbName, tableName, colName); } else if (tableName != null) { parse.ErrorMsg("%s: %s.%s", err, tableName, colName); } else { parse.ErrorMsg("%s: %s", err, colName); } parse.CheckSchema = 1; topNC.Errs++; } // If a column from a table in pSrcList is referenced, then record this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes // bit 0 to be set. Column 1 sets bit 1. And so forth. If the column number is greater than the number of bits in the bitmask // then set the high-order bit of the bitmask. if (expr.ColumnId >= 0 && match != null) { int n = expr.ColumnId; C.ASSERTCOVERAGE(n == BMS - 1); if (n >= BMS) { n = BMS - 1; } Debug.Assert(match.Cursor == expr.TableId); match.ColUsed |= ((Bitmask)1) << n; } // Clean up and return Expr.Delete(ctx, ref expr.Left); expr.Left = null; Expr.Delete(ctx, ref expr.Right); expr.Right = null; expr.OP = (isTrigger ? TK.TRIGGER : TK.COLUMN); lookupname_end: if (cnt == 1) { Debug.Assert(nc != null); Auth.Read(parse, expr, schema, nc.SrcList); // Increment the nRef value on all name contexts from TopNC up to the point where the name matched. for (; ;) { Debug.Assert(topNC != null); topNC.Refs++; if (topNC == nc) { break; } topNC = topNC.Next; } return(WRC.Prune); } return(WRC.Abort); }