Beispiel #1
0
        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);
        }
Beispiel #2
0
        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.");
            }
        }
Beispiel #4
0
        public override void Visit(UpdateSpecification node)
        {
            if (node.WhereClause != null)
            {
                return;
            }

            errorCallback(RULE_NAME, RULE_TEXT, node.StartLine, GetColumnNumber(node));
        }
Beispiel #5
0
        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());
        }
Beispiel #6
0
        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));
        }
Beispiel #8
0
        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());
            }
        }
Beispiel #9
0
        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;
        }
Beispiel #10
0
 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();
                    }
        }
Beispiel #12
0
 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;
     }
 }
Beispiel #13
0
 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);
 }