mattbishop / sql-jsonpath-js

JS implementation of the SQL/JSONPath dialect, from SQL2016.
MIT License
0 stars 0 forks source link

[n to m] range attempt #13

Closed JeffML closed 2 years ago

JeffML commented 2 years ago

I'm still learning, so I expect some criticism. The test explains it best:

        statement: "$.foo.bar[1 to 3].location",
        expected: {
          lhs: [
            {
              property: "foo"
            },
            {
              array: "bar",
              element: {
                start: 1,
                end: 3,
              }
            },
            {
              property: "location"
            },
          ]
        }
      },

I suppose 'element' could be changed to 'range'. Carefully review what I did, in any case.

Parsing [last] and [last - 1] would be similar:

element: {
   last: true,
   offset: <ArithmeticExpression>
}

Offset is optional and I assume offset is always negative relative to last (there are no sensible last + 1 or last * 2 operations; though I suppose last/2 is remotely plausible).

mattbishop commented 2 years ago

A good start, indeed. I did some testing in Postgres and found these statements produce results:

arr[1 to last] arr[1, 3 to 5] arr[1, 3 to 0.5 * last] arr[1, 3 to 0.5 * last - 1] arr[1, 3 to (0.5 * last) + 1]

Perhaps element should be elements so it can hold an array of element declarations?

mattbishop commented 2 years ago

Have a look in the spec (it's at the root of this repo, called SQL-2016_JSON_spec.pdf) section 6.10.3, page 73. It has a BNF of the element accessor syntax. Might give you some good ideas.

JeffML commented 2 years ago

Okay, so it's an arithmetic expression with a fixed variable name.

JeffML commented 2 years ago

Or should say: it's an array of arithmetic expressions.

mattbishop commented 2 years ago

So both start and end are either integers or arithmetic expressions. Also arrays are 1-based so 0 is not a valid index.

JeffML commented 2 years ago

Right. So I think there are three elements that go in that array of indices: wildcard, arithmetic expression (including single digits and last), and ranges. But I haven't read the spec today (recovering from booster).

On Thu, Jan 20, 2022, 9:00 AM Matt Bishop @.***> wrote:

So both start and end are either integers or arithmetic expressions. Also arrays are 1-based so 0 is not a valid index.

— Reply to this email directly, view it on GitHub https://github.com/mattbishop/sql-jsonpath-js/pull/13#issuecomment-1017717414, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2VY3NMFJY6EWEDQJO2Z7TUXA5SHANCNFSM5MLIDGAA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

mattbishop commented 2 years ago

Booster! I had mine last weekend. Took a couple days to get right again.

— Matt Bishop

On Jan 20, 2022, at 12:22 PM, Jeff Lowery @.***> wrote:

 Right. So I think there are three elements that go in that array of indices: wildcard, arithmetic expression (including single digits and last), and ranges. But I haven't read the spec today (recovering from booster).

On Thu, Jan 20, 2022, 9:00 AM Matt Bishop @.***> wrote:

So both start and end are either integers or arithmetic expressions. Also arrays are 1-based so 0 is not a valid index.

— Reply to this email directly, view it on GitHub https://github.com/mattbishop/sql-jsonpath-js/pull/13#issuecomment-1017717414, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2VY3NMFJY6EWEDQJO2Z7TUXA5SHANCNFSM5MLIDGAA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.

JeffML commented 2 years ago

Arrays appear to be 0-based according to the spec. I see 0's all over the place.

Also, this:

but nowhere do they detail what a wff is. Is it an arithmetic expression (including last, which would be a variable)?

You gave me some examples using Postgres which I cannot find now (typical for me when using Google Mail) where you had more elaborate mathematical expressions. Some of those seemed insane.

I added a comment on the issue to better elaborate the requirement.

On Thu, Jan 20, 2022 at 9:00 AM Matt Bishop @.***> wrote:

So both start and end are either integers or arithmetic expressions. Also arrays are 1-based so 0 is not a valid index.

— Reply to this email directly, view it on GitHub https://github.com/mattbishop/sql-jsonpath-js/pull/13#issuecomment-1017717414, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2VY3NMFJY6EWEDQJO2Z7TUXA5SHANCNFSM5MLIDGAA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

mattbishop commented 2 years ago

Right. I am thinking about Postgres whose arrays are 1-based. Good catch!

— Matt Bishop

On Jan 21, 2022, at 3:09 PM, Jeff Lowery @.***> wrote:

 Arrays appear to be 0-based according to the spec. I see 0's all over the place.

Also, this:

  • is the “meat” of an SQL/JSON path expression (“wff” stands for “well-formed formula”).*

but nowhere do they detail what a wff is. Is it an arithmetic expression (including last, which would be a variable)?

You gave me some examples using Postgres which I cannot find now (typical for me when using Google Mail) where you had more elaborate mathematical expressions. Some of those seemed insane.

I added a comment on the issue to better elaborate the requirement.

On Thu, Jan 20, 2022 at 9:00 AM Matt Bishop @.***> wrote:

So both start and end are either integers or arithmetic expressions. Also arrays are 1-based so 0 is not a valid index.

— Reply to this email directly, view it on GitHub https://github.com/mattbishop/sql-jsonpath-js/pull/13#issuecomment-1017717414, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2VY3NMFJY6EWEDQJO2Z7TUXA5SHANCNFSM5MLIDGAA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.

mattbishop commented 2 years ago

For examples check the pull request comments. They should be there?

— Matt Bishop

On Jan 21, 2022, at 3:09 PM, Jeff Lowery @.***> wrote:

 Arrays appear to be 0-based according to the spec. I see 0's all over the place.

Also, this:

  • is the “meat” of an SQL/JSON path expression (“wff” stands for “well-formed formula”).*

but nowhere do they detail what a wff is. Is it an arithmetic expression (including last, which would be a variable)?

You gave me some examples using Postgres which I cannot find now (typical for me when using Google Mail) where you had more elaborate mathematical expressions. Some of those seemed insane.

I added a comment on the issue to better elaborate the requirement.

On Thu, Jan 20, 2022 at 9:00 AM Matt Bishop @.***> wrote:

So both start and end are either integers or arithmetic expressions. Also arrays are 1-based so 0 is not a valid index.

— Reply to this email directly, view it on GitHub https://github.com/mattbishop/sql-jsonpath-js/pull/13#issuecomment-1017717414, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2VY3NMFJY6EWEDQJO2Z7TUXA5SHANCNFSM5MLIDGAA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.

JeffML commented 2 years ago

Okay, I see now that the emails I'm getting about this PR are synced with the comments here. They're easier to follow here in the PR than by Google Mail, so I'll be going here more often.

The simplest explanation of a WFF ("woof") I found:

wff

The image might be too small for you to read, but it's probably not strictly correct anyway.

WFFs are language-dependent. What is the language in this case? Dunno. I don't think it would allow for irrational or imaginary numbers. It may or may not allow power notation. It could allow variables other than last. Maybe negative numbers are allowed (~WFF).

I think the last example you gave, though absolutely insane IMO, is what to shoot for:

arr[1, 3 to (0.5 * last) + 1]

So the parser should consider the following as WFFs:

  1. digits
  2. last
  3. connected WFFs, using +, -, *, /, to as connectors
  4. groups such as (0.5 * last) which contain a WFF

Wildcard $[*] is not a WFF, but a special case that stands alone.

And I that would probably cover just about anything anyone would want to do, plus some.

JeffML commented 2 years ago

Okay, so I think I've got the following working (to my satisfaction):

  1. multiple accessors: [1, 3, 5]
  2. last
  3. simple formulas: [1 + 2, last - 1]
  4. grouped formulas: [1 + (last - 1)]

In this approach, element is an array with at least one lhs member. So, foo[1] parsed to something like `{element:[{lhs:1}]. That may seem more complicated, but it is consistent, so the consumer of the CST doesn't need to handle single accessors differently from multiple accessors.

STILL BROKED: I don't handle the multiple connector case, e.g. foo[1+2+3]

JeffML commented 2 years ago

Looks pretty nice! Why do you think it won't handle arr[1 + 2 + 3]?

WFF = WFF connector WFF; 1 + 2 + 3 is WFF connector WFF connector WFF

Not exactly sure how to deal with this:

  1. convert to an array of WFF's and connectors (if that is doable)
  2. recursively deal with WFFs: WFF connector WFF connector WFF = WFF' connector WFF = WFF''
mattbishop commented 2 years ago

@JeffML any other changes or are you ready for me to merge this?

JeffML commented 2 years ago

I took a look at Chevrolet trains calculator program and I think I figured out how to do the chain of operations inspirations that I said could be done so you can hold off on that if you want.

On Thu, Jan 27, 2022, 6:15 AM Matt Bishop @.***> wrote:

@JeffML https://github.com/JeffML any other changes or are you ready for me to merge this?

— Reply to this email directly, view it on GitHub https://github.com/mattbishop/sql-jsonpath-js/pull/13#issuecomment-1023254111, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2VY3PT27UFDHGWNUULC5TUYFHPDANCNFSM5MLIDGAA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

mattbishop commented 2 years ago

Cool, I'll wait then.

JeffML commented 2 years ago

rhs is now an array of ops with connector and rhs members.

JeffML commented 2 years ago

I'm done now.

mattbishop commented 2 years ago

Thanks Jeff!