Skip to content

Commit

Permalink
Expose CURRENT_USER as entity reference
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Nov 21, 2021
1 parent cce0318 commit 1234520
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 20 deletions.
4 changes: 3 additions & 1 deletion MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ void IQueryExecutionOptions.RetrievingNextPage()
{
}

string IQueryExecutionOptions.PrimaryDataSource => "local";

Guid IQueryExecutionOptions.UserId => Guid.NewGuid();

[TestMethod]
Expand Down Expand Up @@ -2996,7 +2998,7 @@ public void CrossInstanceJoin()
TableSizeCache = new StubTableSizeCache()
}
};
var planBuilder = new ExecutionPlanBuilder(datasources, "uat", this);
var planBuilder = new ExecutionPlanBuilder(datasources, this);

var query = "SELECT uat.name, prod.name FROM uat.dbo.account AS uat INNER JOIN prod.dbo.account AS prod ON uat.accountid = prod.accountid WHERE uat.name <> prod.name AND uat.name LIKE '%test%'";

Expand Down
2 changes: 2 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/Sql2FetchXmlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ void IQueryExecutionOptions.RetrievingNextPage()
{
}

string IQueryExecutionOptions.PrimaryDataSource => "local";

Guid IQueryExecutionOptions.UserId => Guid.NewGuid();

[TestMethod]
Expand Down
2 changes: 2 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/StubOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ void IQueryExecutionOptions.RetrievingNextPage()
{
}

string IQueryExecutionOptions.PrimaryDataSource => "local";

Guid IQueryExecutionOptions.UserId => Guid.NewGuid();
}
}
4 changes: 2 additions & 2 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,9 +1197,9 @@ private static SqlDateTime GetCurrentTimestamp(IQueryExecutionOptions options)
return new SqlDateTime(DateTime.UtcNow);
}

private static SqlGuid GetCurrentUser(IQueryExecutionOptions options)
private static SqlEntityReference GetCurrentUser(IQueryExecutionOptions options)
{
return options.UserId;
return new SqlEntityReference(options.PrimaryDataSource, "systemuser", options.UserId);
}

/// <summary>
Expand Down
22 changes: 8 additions & 14 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlanBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ public class ExecutionPlanBuilder
private int _colNameCounter;

public ExecutionPlanBuilder(IAttributeMetadataCache metadata, ITableSizeCache tableSize, IQueryExecutionOptions options)
: this(new[] { new DataSource { Name = "local", Metadata = metadata, TableSizeCache = tableSize } }, "local", options)
: this(new[] { new DataSource { Name = "local", Metadata = metadata, TableSizeCache = tableSize } }, options)
{
}

public ExecutionPlanBuilder(IEnumerable<DataSource> dataSources, string primaryDataSource, IQueryExecutionOptions options)
public ExecutionPlanBuilder(IEnumerable<DataSource> dataSources, IQueryExecutionOptions options)
{
DataSources = dataSources.ToDictionary(ds => ds.Name, StringComparer.OrdinalIgnoreCase);
PrimaryDataSource = primaryDataSource;
Options = options;
}

Expand All @@ -37,11 +36,6 @@ public ExecutionPlanBuilder(IEnumerable<DataSource> dataSources, string primaryD
/// </summary>
public IDictionary<string, DataSource> DataSources { get; }

/// <summary>
/// The name of the connection that will be used by default
/// </summary>
public string PrimaryDataSource { get; set; }

/// <summary>
/// Returns or sets a value indicating if SQL will be parsed using quoted identifiers
/// </summary>
Expand Down Expand Up @@ -212,15 +206,15 @@ private ExecuteAsNode ConvertExecuteAsStatement(ExecuteAsStatement impersonate)
{
UserIdSource = "systemuser.systemuserid",
Source = source,
DataSource = PrimaryDataSource
DataSource = Options.PrimaryDataSource
};
}

private RevertNode ConvertRevertStatement(RevertStatement revert)
{
return new RevertNode
{
DataSource = PrimaryDataSource
DataSource = Options.PrimaryDataSource
};
}

Expand Down Expand Up @@ -301,7 +295,7 @@ private IExecutionPlanNode ConvertInsertSelectSource(SelectInsertSource selectSo

private DataSource SelectDataSource(SchemaObjectName schemaObject)
{
var databaseName = schemaObject.DatabaseIdentifier?.Value ?? PrimaryDataSource;
var databaseName = schemaObject.DatabaseIdentifier?.Value ?? Options.PrimaryDataSource;

if (!DataSources.TryGetValue(databaseName, out var dataSource))
throw new NotSupportedQueryFragmentException("Invalid database name", schemaObject) { Suggestion = $"Available database names:\r\n* {String.Join("\r\n*", DataSources.Keys.OrderBy(k => k))}" };
Expand Down Expand Up @@ -526,7 +520,7 @@ private DeleteNode ConvertDeleteStatement(DeleteSpecification delete, IList<Opti
TopRowFilter = delete.TopRowFilter
};

var deleteTarget = new UpdateTargetVisitor(target.SchemaObject, PrimaryDataSource);
var deleteTarget = new UpdateTargetVisitor(target.SchemaObject, Options.PrimaryDataSource);
queryExpression.FromClause.Accept(deleteTarget);

if (String.IsNullOrEmpty(deleteTarget.TargetEntityName))
Expand Down Expand Up @@ -680,7 +674,7 @@ private UpdateNode ConvertUpdateStatement(UpdateSpecification update, IList<Opti
TopRowFilter = update.TopRowFilter
};

var updateTarget = new UpdateTargetVisitor(target.SchemaObject, PrimaryDataSource);
var updateTarget = new UpdateTargetVisitor(target.SchemaObject, Options.PrimaryDataSource);
queryExpression.FromClause.Accept(updateTarget);

if (String.IsNullOrEmpty(updateTarget.TargetEntityName))
Expand Down Expand Up @@ -940,7 +934,7 @@ private IRootExecutionPlanNode ConvertSelectStatement(SelectStatement select)
if (Options.UseTDSEndpoint && TDSEndpointAvailable)
{
select.ScriptTokenStream = null;
return new SqlNode { DataSource = PrimaryDataSource, Sql = select.ToSql() };
return new SqlNode { DataSource = Options.PrimaryDataSource, Sql = select.ToSql() };
}

if (select.ComputeClauses != null && select.ComputeClauses.Count > 0)
Expand Down
4 changes: 2 additions & 2 deletions MarkMpn.Sql4Cds.Engine/ExpressionFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,9 @@ public static SqlInt32 CharIndex(SqlString find, SqlString search, SqlInt32 star
/// </summary>
/// <param name="options">The options that provide access to the user details</param>
/// <returns></returns>
public static SqlGuid User_Name(IQueryExecutionOptions options)
public static SqlEntityReference User_Name(IQueryExecutionOptions options)
{
return options.UserId;
return new SqlEntityReference(options.PrimaryDataSource, "systemuser", options.UserId);
}

/// <summary>
Expand Down
5 changes: 5 additions & 0 deletions MarkMpn.Sql4Cds.Engine/IQueryExecutionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ public interface IQueryExecutionOptions
/// </summary>
void RetrievingNextPage();

/// <summary>
/// Returns the name of the primary data source the query is being executed in
/// </summary>
string PrimaryDataSource { get; }

/// <summary>
/// Returns the unique identifier of the current user
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions MarkMpn.Sql4Cds.Engine/Sql2FetchXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public QueryExecutionOptions(Sql2FetchXml sql2FetchXml)

public bool UseLocalTimeZone => false;

public string PrimaryDataSource => "local";

public Guid UserId { get; set; }

public List<JoinOperator> JoinOperatorsAvailable => new List<JoinOperator> { JoinOperator.Inner, JoinOperator.LeftOuter };
Expand Down
2 changes: 2 additions & 0 deletions MarkMpn.Sql4Cds/QueryExecutionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ public void RetrievingNextPage()
throw new QueryExecutionException($"Hit maximum retrieval limit. This limit is in place to protect against excessive API requests. Try restricting the data to retrieve with WHERE clauses or eliminating subqueries.\r\nYour limit of {Settings.Instance.MaxRetrievesPerQuery:N0} retrievals per query can be modified in Settings.");
}

public string PrimaryDataSource => _con.ConnectionName;

public Guid UserId
{
get
Expand Down
2 changes: 1 addition & 1 deletion MarkMpn.Sql4Cds/SqlQueryControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
backgroundWorker.ReportProgress(0, "Executing query...");

var options = new QueryExecutionOptions(_con, DataSources[_con.ConnectionName].Connection, backgroundWorker, this);
var converter = new ExecutionPlanBuilder(DataSources.Values, _con.ConnectionName, options);
var converter = new ExecutionPlanBuilder(DataSources.Values, options);

if (Settings.Instance.UseTSQLEndpoint &&
args.Execute &&
Expand Down

0 comments on commit 1234520

Please sign in to comment.