Skip to content

Fix snowflake error : "Lateral cannot be on the left side of join"#2074

Closed
amitaggarwal1 wants to merge 2 commits intomalloydata:mainfrom
datairisplatform:amit/sflake_ljoin
Closed

Fix snowflake error : "Lateral cannot be on the left side of join"#2074
amitaggarwal1 wants to merge 2 commits intomalloydata:mainfrom
datairisplatform:amit/sflake_ljoin

Conversation

@amitaggarwal1
Copy link
Collaborator

For nested fields we were using lateral flatten. The issue with it is that if the

nested field is used in a join, snowflake complains that lateral flatten can't be on left side of join (https://stackoverflow.com/questions/63397022/snowflake-lateral-cannot-be-on-the-left-side-of-join)

fix is to always convert lateral flatten to a left join

Also simplify the array[scalar] vs array[record] treatment. earlier, at the unnesting step we were creating a object for array[scalar] case to make it consistent with the array[record] case. Now at the reference time, based on the case, use the right expression

  • array[record] : parent.value:sql_field
  • array[scalar] : parent.value

… that if the

nested field is used in a join, snowflake complains that lateral flatten can't be
on left side of join (https://stackoverflow.com/questions/63397022/snowflake-lateral-cannot-be-on-the-left-side-of-join)

fix is to always convert lateral flatten to a left join

Also simplify the array[scalar] vs array[record] treatment. earlier, at the
unnesting step we were creating a object for array[scalar] case to make it
consistent with the array[record] case. Now at the reference time, based on
the case, use the right expression
- array[record] : parent.value:sql_field
- array[scalar] : parent.value

Signed-off-by: Amit Aggarwal <[email protected]>
): string {
const as = this.sqlMaybeQuoteIdentifier(alias);
if (isArray) {
return `,LATERAL FLATTEN(INPUT => ${source}) AS ${alias}_1, LATERAL (SELECT ${alias}_1.INDEX, object_construct('value', ${alias}_1.value) as value ) as ${as}`;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would imagine some tests are failing. The INDEX is the distinct key and necessary for deduping.

It would also be great to have a test that shows what this fixes..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will work on fixing the tests.

Re: INDEX, INDEX is already part of the flatten structure. This was taking something of the form {INDEX: i, value: v} and converting into {INDEX: i, value: {value: v}}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lloydtabb added test case. this test fails without the fix with the following error:

 query.run failed: SQL compilation error:
    Lateral View cannot be on the left side of join
    SQL: SELECT
       a_0."a_two" as "a_two"
    FROM (
          SELECT [2,4,6,8] AS "evens"
        ) as base
    ,LATERAL FLATTEN(INPUT => base."evens") AS evens_0_1, LATERAL (SELECT evens_0_1.INDEX, object_construct('value', evens_0_1.value) as value ) as "evens_0"
     LEFT JOIN ( SELECT 2 as "a_two" ) AS a_0
      ON a_0."a_two"="evens_0".value:"value"::DOUBLE

    OperationFailedError: SQL compilation error:
    Lateral View cannot be on the left side of join

Signed-off-by: Amit Aggarwal <[email protected]>
@lloydtabb
Copy link
Collaborator

So this is a bigger (and long standing) problem. Malloy, generally, can't join on a nested field. I think I finally know now to fix it, but it is a pretty major rework of code generation. It's probably worth scheduling the work.

I'm curious to see how your test fares on the other dialects.

#1481

We're working on figuring out how to get tests running against external pull requests (that's the reason for the delay in merging).

@lloydtabb
Copy link
Collaborator

You can see that it fails in other dialects.

https://github.com/malloydata/malloy/actions/runs/12605890168/job/35135261018?pr=2074#step:4:223

I'll write up what I think the solution is in the #1481

lloydtabb added a commit that referenced this pull request Jan 8, 2025

describe('simple arrays', () => {
test('join on scalar array field', async () => {
const nestedArrayJoin = `
Copy link
Collaborator

@mtoy-googly-moogly mtoy-googly-moogly Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

        const nestedArrayJoin = `
           source: a is ${conName}.sql(""" SELECT 2 as ${quote('a_two')} """)
           source: b is ${evens} extend { join_one: a is a on a.a_two = evens.value}
           run: b -> {select: a_two is a.a_two}`;

parentType === 'array[record]'
) {
const arrayRef = `"${parentAlias}".value:${sqlName}`;
// Case 1: this is an array of scalar. We can reference the field
Copy link
Collaborator

@mtoy-googly-moogly mtoy-googly-moogly Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure I know what is going because I don't have the un-nested state of the array exactly in my head at this moment, but something like this would be preferable, if this is the correct solution.

      const arrayRef = `"${parentAlias}".value` + (parentType === 'array[record]' ? `:${sqlName}`: '');

mtoy-googly-moogly added a commit that referenced this pull request Jan 11, 2025
* Add these changes from #2072 and #2074

* Need to also change the way arrays are unnested.

* mtoy's take on the changes ... passes ci-snowflake

* add fix and test for array names ending in numbers

* Add changes from #2088

* delete line for linter

---------

Co-authored-by: Michael Toy <[email protected]>
@mtoy-googly-moogly
Copy link
Collaborator

#2086 has these changes in it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants