public ISyntaxNode Visit(TSqlFragment node, TSqlFragment parent, string sourceProperty, ISyntaxNode result) { UpdateSpecification update = node as UpdateSpecification; if (update == null) { return(result); } StatementNode statement = new StatementNode() { Parent = result, Fragment = node, ParentFragment = parent, TargetProperty = sourceProperty }; if (result is ScriptNode script) { if (parent is UpdateStatement) { script.Statements.Add(statement); return(statement); } } return(result); }
protected override object InternalVisit(UpdateSpecification node) { //TODO:node.FromClause //TODO:node.OutputIntoClause var env = Database.GlobalEnvironment.NewChild(); var table = (Table)Visit <IResultTable>(node.Target); var top = EvaluateExpression <TopResult>(node.TopRowFilter, env); var predicate = EvaluateExpression <Func <Row, bool> >(node.WhereClause, env, row => true); Action <Row> setClause = CreateSetClause(node.SetClauses, env); List <Row> rows = new List <Row>(); rows.AddRange(Filter.From(table.Rows, predicate, top)); foreach (var item in rows) { setClause(item); } table.AcceptChanges(); return(new SQLExecutionResult(rows.Count(), ApplyOutputClause(new RecordTable("UPDATED", table.Columns, rows), node.OutputClause))); }
public override void Visit(UpdateSpecification node) { base.Visit(node); if (node.WhereClause == null) { AddFinding(node, "UPDATE without WHERE clause."); } }
public override void Visit(UpdateSpecification node) { if (node.WhereClause != null) { return; } errorCallback(RULE_NAME, RULE_TEXT, node.StartLine, GetColumnNumber(node)); }
public static IEnumerable <SchemaObjectReference> GetSchemaObjectReferences( this UpdateSpecification updateSpecification, ILogger logger, SchemaFile file ) { var databaseObjectReferences = updateSpecification .FromClause ?.TableReferences .GetSchemaObjectReferences(logger, file) .ToList() ?? new List <SchemaObjectReference>(); SchemaObjectReference targetReference; using (new StatementContext(file.FileContext, databaseObjectReferences)) { targetReference = updateSpecification .Target .GetSchemaObjectReferences(logger, file) .First(); } // TODO : would it be a big deal if I add it twice? it would simplify the logic here if (!databaseObjectReferences .Any(x => string.Equals(x.Alias, targetReference.Alias) && string.Equals(x.Identifier, targetReference.Identifier))) { databaseObjectReferences.Add(targetReference); } var outputIntoReferences = new List <SchemaObjectReference>() { new SchemaObjectReference() { Alias = "inserted", Identifier = targetReference.Identifier, Value = targetReference.Value }, new SchemaObjectReference() { Alias = "deleted", Identifier = targetReference.Identifier, Value = targetReference.Value } }; return(databaseObjectReferences .Concat(outputIntoReferences) .ToList()); }
public static EngineResult Evaluate(DataModificationSpecification dml, Scope scope) { IOutputSink sink; // TODO: support scalar expressions in TableOutputSink, not just column names // how to handle INSERTED. and DELETED. aliases? if (dml.OutputClause != null || dml.OutputIntoClause != null) { sink = new TableOutputSink( (dml.OutputClause?.SelectColumns ?? dml.OutputIntoClause?.SelectColumns)? .Select(s => new Column { Name = ((ColumnReferenceExpression)((SelectScalarExpression)s).Expression) .MultiPartIdentifier.Identifiers.Select(x => x.Value).ToArray(), Type = DbType.AnsiString }).ToList()); } else { sink = new NullOutputSink(); } var result = dml switch { InsertSpecification insert => Evaluate(insert, sink, scope), MergeSpecification merge => Evaluate(merge, sink, scope), DeleteSpecification delete => Evaluate(delete, sink, scope), UpdateSpecification update => Evaluate(update, sink, scope), _ => throw FeatureNotSupportedException.Subtype(dml) }; if (dml.OutputIntoClause != null) { var(table, scope2) = Evaluate(dml.OutputIntoClause.IntoTable, null, scope); Evaluate( table, dml.OutputIntoClause.IntoTableColumns, ((TableOutputSink)sink).Output, new NullOutputSink(), scope2); } return(dml.OutputClause != null ? new EngineResult(((TableOutputSink)sink).Output) : result); } }
public static EngineResult Evaluate(UpdateSpecification update, IOutputSink sink, Scope scope) { var tableRef = (NamedTableReference)update.Target; var table = scope.Env.Tables[tableRef.SchemaObject.BaseIdentifier.Value]; var rowCount = 0; foreach (var row in table.Rows) { if (update.WhereClause == null || Evaluate(update.WhereClause.SearchCondition, new RowArgument(row), scope)) { Evaluate(update.SetClauses, row, row, sink, scope); rowCount++; } } scope.Env.RowCount = rowCount; return(new EngineResult(rowCount)); }
public static IList <FieldPairReference> GetFieldPairReferences( this UpdateSpecification updateSpecification, ILogger logger, SchemaFile file ) { var newReferences = updateSpecification .GetSchemaObjectReferences(logger, file) .ToList(); using (new StatementContext(file.FileContext, newReferences)) { var setClausePairs = updateSpecification .SetClauses .GetFieldPairs(logger, file) .ToList(); var fromCalusePairs = updateSpecification .FromClause ?.TableReferences .GetFieldPairs(logger, file) ?? new List <FieldPairReference>(); var whereClauePairs = updateSpecification .WhereClause ?.SearchCondition .GetFieldPairs(logger, file) ?? new List <FieldPairReference>(); var outputIntoPairs = updateSpecification .OutputIntoClause ?.GetFieldPairs(logger, file) ?? new List <FieldPairReference>(); return(setClausePairs .Concat(fromCalusePairs) .Concat(whereClauePairs) .Concat(outputIntoPairs) .ToList()); } }
private WSqlStatement ParseUpdateStatement(UpdateSpecification upSpec) { if (upSpec == null) return null; var wupSpec = new WUpdateSpecification { Target = ParseTableReference(upSpec.Target), FirstTokenIndex = upSpec.FirstTokenIndex, LastTokenIndex = upSpec.LastTokenIndex }; //TopRowFilter if (upSpec.TopRowFilter != null) { wupSpec.TopRowFilter = new WTopRowFilter { Percent = upSpec.TopRowFilter.Percent, WithTies = upSpec.TopRowFilter.WithTies, Expression = ParseScalarExpression(upSpec.TopRowFilter.Expression), FirstTokenIndex = upSpec.TopRowFilter.FirstTokenIndex, LastTokenIndex = upSpec.TopRowFilter.LastTokenIndex }; } //From Clause if (upSpec.FromClause != null && upSpec.FromClause.TableReferences != null) { wupSpec.FromClause = new WFromClause { FirstTokenIndex = upSpec.FromClause.FirstTokenIndex, LastTokenIndex = upSpec.FromClause.LastTokenIndex, TableReferences = new List<WTableReference>(upSpec.FromClause.TableReferences.Count) }; foreach (var pref in upSpec.FromClause.TableReferences.Select(ParseTableReference).Where(pref => pref != null)) { wupSpec.FromClause.TableReferences.Add(pref); } } //Where Clause if (upSpec.WhereClause != null && upSpec.WhereClause.SearchCondition != null) { wupSpec.WhereClause = new WWhereClause { FirstTokenIndex = upSpec.WhereClause.FirstTokenIndex, LastTokenIndex = upSpec.WhereClause.LastTokenIndex, SearchCondition = ParseBooleanExpression(upSpec.WhereClause.SearchCondition) }; } //Set Clauses IList<WSetClause> wsetClauses = new List<WSetClause>(upSpec.SetClauses.Count); foreach (var setClause in upSpec.SetClauses) { WSetClause wsetClause; switch (setClause.GetType().Name) { case "AssignmentSetClause": { var asSetClause = setClause as AssignmentSetClause; wsetClause = ParseAssignmentSetClause(asSetClause); break; } case "FunctionCallSetClause": { var fcSetClause = setClause as FunctionCallSetClause; var mtFunction = fcSetClause.MutatorFunction; wsetClause = new WFunctionCallSetClause { MutatorFuction = ParseScalarExpression(mtFunction) as WFunctionCall }; break; } default: continue; } wsetClauses.Add(wsetClause); } wupSpec.SetClauses = wsetClauses; return wupSpec; }
public static void UpdateOriginal(UpdateSpecification update){ if (update == null){Debug.Assert(false); return;} Updater updater = new Updater(); updater.Visit(update.Original, update.Changes, update.Deletions, update.Insertions); }
public void UpdateItems <T>(IEnumerable <T> items, string schema, string tableName, IList <ColumnMapping> properties, DbConnection storeConnection, int?batchSize, UpdateSpecification <T> updateSpecification) { var tempTableName = $"temp_{tableName}_{DateTime.Now.Ticks}"; var columnsToUpdate = updateSpecification.Properties.Select(p => p.GetPropertyName()).ToDictionary(x => x); var filtered = properties.Where(p => columnsToUpdate.ContainsKey(p.NameOnObject) || p.IsPrimaryKey).ToList(); var columns = filtered.Select(c => $"[{c.NameInDatabase}] {c.DataType}"); var pkConstraint = string.Join(", ", properties.Where(p => p.IsPrimaryKey).Select(c => $"[{c.NameInDatabase}]")); var str = $"CREATE TABLE {schema}.[{tempTableName}]({string.Join(", ", columns)}, PRIMARY KEY ({pkConstraint}))"; var con = storeConnection as SqlConnection; if (con != null && con.State != ConnectionState.Open) { con.Open(); } var setters = string.Join(",", filtered.Where(c => !c.IsPrimaryKey).Select(c => $"[{c.NameInDatabase}] = TEMP.[{c.NameInDatabase}]")); var pks = properties.Where(p => p.IsPrimaryKey).Select(x => $"ORIG.[{x.NameInDatabase}] = TEMP.[{x.NameInDatabase}]"); var filter = string.Join(" and ", pks); var mergeCommand = $@"UPDATE [{tableName}] SET {setters} FROM [{tableName}] ORIG INNER JOIN [{tempTableName}] TEMP ON {filter}"; using (var createCommand = new SqlCommand(str, con)) using (var mCommand = new SqlCommand(mergeCommand, con)) using (var dCommand = new SqlCommand($"DROP table {schema}.[{tempTableName}]", con)) { createCommand.ExecuteNonQuery(); InsertItems(items, schema, tempTableName, filtered, storeConnection, batchSize); mCommand.ExecuteNonQuery(); dCommand.ExecuteNonQuery(); } }
void SymbolTableUpdateEventHandler(Compilation updatedSymbolTable, UpdateSpecification updateSpecification, MemberList changedMembers) { lock (this){ Thread savedCurrentThread = this.currentThread; if (Thread.CurrentThread == this.currentThread) { Console.WriteLine("Update event called on same thread as the one causing the update"); } if (!Thread.CurrentThread.IsThreadPoolThread) { Console.WriteLine("Updated event called from a non thread pool thread"); } if (!Thread.CurrentThread.IsBackground) { Console.WriteLine("Updated event called from a non background thread"); } this.currentThread = Thread.CurrentThread; if (updatedSymbolTable == null) { Console.WriteLine("SymbolTable update with null value for updatedSymbolTable"); return; } if (updatedSymbolTable.TargetModule == null) { Console.WriteLine("SymbolTable update with null value for updatedSymbolTable.TargetModule"); return; } Console.WriteLine("Received update event on symbol table: {0}", ((Compilation)updateSpecification.Original).TargetModule.Name); for (int i = 0, n = changedMembers == null ? 0 : changedMembers.Count; i < n; i++) { Member mem = changedMembers[i]; if (mem == null) { Console.WriteLine("changedMembers[{0}] == null", i); } else { Console.WriteLine("changedMembers[{0}].FullName == {1}", i, mem.FullName); } } for (int i = 0, n = this.compilations.Count; i < n; i++) { Compilation compilation = this.compilations[i]; if (compilation == null || compilation == updateSpecification.Original) { continue; } for (int j = 0, m = compilation.ReferencedCompilations == null ? 0 : compilation.ReferencedCompilations.Count; j < m; j++) { Compilation rComp = compilation.ReferencedCompilations[j]; if (rComp != updateSpecification.Original) { continue; } Compilation upd = this.compiler.UpdateSymbolTable(compilation, (Compilation)updateSpecification.Original, updatedSymbolTable, changedMembers, this.errors); if (upd == null) { Console.WriteLine("Referenced compilation {0} was not updated", j); } else { this.CheckUpdatedCompilation(compilation, upd); } } } this.currentThread = savedCurrentThread; } }
public override void Visit(UpdateSpecification node) { this.action(node); }
public override void ExplicitVisit(UpdateSpecification fragment) { _fragments.Add(fragment); }
public void FireOnSymbolTableUpdate(Compilation updatedSymbolTable, UpdateSpecification updateSpecification, MemberList changedMembers){ this.OnSymbolTableUpdate.BeginInvoke(updatedSymbolTable, updateSpecification, changedMembers, null, null); }