/// <summary> /// Get the partitions for a specific table /// </summary> /// <param name="tableName">The name of the table</param> /// <param name="canHandleMultiplePartitions">True if the caller can handle getting multiple partitions</param> /// <param name="sqlTree">The SQL tree that can be modified to give the user the correct partitions</param> /// <param name="httpContext">The http context that contains user information etc.</param> /// <returns></returns> public virtual Task <IImmutableList <Partition> > GetPartitions(bool canHandleMultiplePartitions, PartitionsBuilder partitionsBuilder, HttpContext httpContext, PartitionOptions partitionOptions) { return(Task.FromResult <IImmutableList <Partition> >(ImmutableList.Create <Partition>(partitionsBuilder.NewPartition().Build()))); }
public async Task <Transport.TransportPartitionsResult> GetPartitions(bool canHandlePartitions, string sql, SqlParameters sqlParameters, HttpContext httpContext) { var sqlTree = _sqlParser.Parse(sql, out var errors); foreach (var header in httpContext.Request.Headers) { if (header.Key.StartsWith("P_", StringComparison.OrdinalIgnoreCase)) { var parameterName = header.Key.Substring(2); if (header.Value.Count > 1) { throw new SqlErrorException("Two parameters found with the same name in the http headers."); } var value = header.Value.First(); var base64Value = Convert.ToBase64String(Encoding.UTF8.GetBytes(value)); //Add the parameter as base64 inline parameter sqlTree.Statements.Insert(0, new SetVariableStatement() { VariableReference = new SqlParser.Expressions.VariableReference() { Name = parameterName }, ScalarExpression = new Base64Literal() { Value = base64Value } }); } } if (errors.Count > 0) { throw new SqlErrorException(errors.First().Message); } //Apply the row level security filter on the query await RowLevelSecurityHelper.ApplyRowLevelSecurity(sqlTree, httpContext, _metadataStore, _serviceProvider); var schema = _sqlExecutor.GetSchema(sqlTree, sqlParameters); //Take table name and get the partition resolver if (!_metadataStore.TryGetTable(schema.TableName, out var table)) { throw new SqlErrorException($"The table {schema.TableName} was not found."); } //Get the partitions var discoveryService = _serviceProvider.GetService <IDiscoveryService>(); var partitionsBuilder = new PartitionsBuilder(sqlTree); var partitions = await table.PartitionResolver.GetPartitions(canHandlePartitions, partitionsBuilder, httpContext, new PartitionOptions(_serviceProvider, discoveryService)); var partitionListBuilder = ImmutableList.CreateBuilder <Transport.TransportPartition>(); foreach (var partition in partitions) { List <TransportServiceLocation> locations = new List <TransportServiceLocation>(); foreach (var location in partition.Locations) { locations.Add(new TransportServiceLocation(location.Host, location.Tls)); } partitionListBuilder.Add(new Transport.TransportPartition(locations, partition.SqlTree.Print())); } return(new Transport.TransportPartitionsResult(ConvertColumns(schema.Columns), partitionListBuilder.ToImmutable())); }