Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linq.Expressions array indexer get maps to GetArray, not get_Item #16918

Open
bartelink opened this issue Mar 21, 2024 · 0 comments
Open

Linq.Expressions array indexer get maps to GetArray, not get_Item #16918

bartelink opened this issue Mar 21, 2024 · 0 comments
Labels
Area-Queries Query expressions and library implementation Bug Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code.
Milestone

Comments

@bartelink
Copy link

bartelink commented Mar 21, 2024

Please provide a succinct description of the issue.

Array indexing within a an Expression<'A -> 'B> is mapped to a GetArray call (in line with how it works for Expr ?) rather than a get_Item invocation.

There does not appear to be a clean workaround aside from using a list or a ResizeArray instead (as the get_Item mechanism is not exposed).

Provide the steps required to reproduce the problem:

#r "nuget: Microsoft.Azure.Cosmos, 3.38.1"

open Microsoft.Azure.Cosmos
open Microsoft.Azure.Cosmos.Linq
open System.Linq

type Doc =
    {   p: string
        u: Unfold[] }
and Unfold =
    {   c: string }
let client = new CosmosClient(conns)
let c = client.GetDatabase("name").GetContainer("container")
let q = c.GetItemLinqQueryable<Doc>(allowSynchronousQueryExecution = true)
let i = q.Where(fun x -> x.p = "Snapshotted" )
         .OrderBy(fun d -> d.u[0].c)
         .Select(fun x -> x.u.[0].c)
printfn "%O" i.Expression
printfn "%s" (i.ToQueryDefinition().QueryText)
for x in i.Take(2) do
    printfn $"%A{x}"

Expected behavior

Should generate System.Linq.Expression.Expression of the form:

dbs/name/colls/container.Where(x => (x.p == "Snapshotted")).OrderBy(d => d.u.get_Item(0).c).Select(x => x.u.get_Item(0).c)

Which yields correct SQL:

SELECT VALUE root["u"][0]["c"] FROM root WHERE (root["p"] = "Snapshotted") ORDER BY root["u"][0]["c"] ASC

Actual behavior

dbs/name/colls/container.Where(x => (x.p == "Snapshotted")).OrderBy(d => GetArray(d.u, 0).c).Select(x => GetArray(x.u, 0).c)

Microsoft.Azure.Cosmos.Linq.DocumentQueryException: Method 'GetArray' is not supported.

NOTE other approaches such as using query { run aground for the same fundamental reason (mapping to a surprising F#-specific expression tree)

Known workarounds

  • Switch the u: Unfold[] to be a ResizeArray (or even a list !)

Related information

**C# equivalent (for completeness, yields same get_Item invocation)

using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;

var client = new CosmosClient(conns);
var c = client.GetDatabase("database").GetContainer("container");
var q = c.GetItemLinqQueryable<Doc>(allowSynchronousQueryExecution: true);
var i = q.Select(d => d.u[0].c);

Console.WriteLine(i.Expression);
Console.WriteLine(i.ToQueryDefinition().QueryText);
Console.WriteLine(i);

foreach (var x in i.Take(2))
    Console.WriteLine(x);

record Doc(String p, Unfold[] u);
record Unfold(String c, int i, Index d);
record Index(string k, int v);
@github-actions github-actions bot added this to the Backlog milestone Mar 21, 2024
@bartelink bartelink changed the title System.Linq.Expressions array indexer get maps to GetArray, not get_Item Linq.Expressions array indexer get maps to GetArray, not get_Item Mar 21, 2024
@abonie abonie added Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code. Area-Queries Query expressions and library implementation and removed Needs-Triage labels Mar 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Queries Query expressions and library implementation Bug Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code.
Projects
Status: New
Development

No branches or pull requests

2 participants