private IQueryModel EnsureModel() { if (_model == null) { if (statement is SelectStatement stmt_sel) { _model = QueryModelLoader.LoadModel(batchResolver, "roooot", stmt_sel.QueryExpression, stmt_sel.WithCtesAndXmlNamespaces); } else { DataModificationSpecification source_specification = null; DataModificationStatement stmt_mod = (DataModificationStatement)statement; if (statement is InsertStatement stmt_ins) { source_specification = stmt_ins.InsertSpecification; } else if (statement is UpdateStatement stmt_upd) { source_specification = stmt_upd.UpdateSpecification; } else if (statement is DeleteStatement stmt_del) { source_specification = stmt_del.DeleteSpecification; } else if (statement is MergeStatement stmt_mrg) { source_specification = stmt_mrg.MergeSpecification; } _model = QueryModelLoader.LoadModificationOutputModel(batchResolver, "roooot", source_specification, stmt_mod.WithCtesAndXmlNamespaces); } } return(_model); }
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); } }
private OutputColumnDescriptor TryResolveColumnReferenceCoreSN(TSqlFragment node, string sourceNameOrAlias, string columnName) { OutputColumnDescriptor resultColumnType; if (statement is SelectStatement stmt_sel) { if (TryQueryExpression(stmt_sel.QueryExpression, stmt_sel.WithCtesAndXmlNamespaces, sourceNameOrAlias, columnName, out resultColumnType)) { return(resultColumnType); } return(null); // resolved failed!!! } if (statement is DataModificationStatement stmt_mod) { WithCtesAndXmlNamespaces source_ctes = stmt_mod.WithCtesAndXmlNamespaces; DataModificationSpecification source_specification = null; if (statement is InsertStatement stmt_ins && string.Equals(sourceNameOrAlias, "INSERTED", StringComparison.OrdinalIgnoreCase)) { source_specification = stmt_ins.InsertSpecification; } else if (statement is UpdateStatement stmt_upd) { source_specification = stmt_upd.UpdateSpecification; } else if (statement is DeleteStatement stmt_del) { source_specification = stmt_del.DeleteSpecification; } else if (statement is MergeStatement stmt_mrg) { source_specification = stmt_mrg.MergeSpecification; } if (source_specification != null && source_specification.OutputClause != null) { if (TryTableReference(true, true, source_specification.Target, source_ctes, null, columnName, out resultColumnType)) { return(resultColumnType); } throw new NotImplementedException("Target could not be found." + statement.WhatIsThis()); } }
public QueryOnModificationOutputModel(int id, DataModificationSpecification mspec, string key) : base(id, key) { MSpec = mspec; }
public override void ExplicitVisit(DataModificationSpecification fragment) { _fragments.Add(fragment); }
public QueryOnModificationOutputModel NewRootOnModificationOutput(DataModificationSpecification mspec, string key) { lastid++; return(new QueryOnModificationOutputModel(lastid, mspec, key)); }
public sealed override void ExplicitVisit(DataModificationSpecification node) { base.ExplicitVisit(node); }
public override void ExplicitVisit(DataModificationSpecification node) { this.action(node); }