undefined method `inline' for nil:NilClass -- from referencing SQL_TABLE_NAME

Hi, is anybody familiar with the following error:

undefined method `inline’ for nil:NilClass

I get this when I try to reference a dimension in my SQL-based derived table, the the referenced dimension includes a view.SQL_TABLE_NAME statement.

My real use-case involves a base view and 4 views that extend that base view. I’m using these dimensions basically like “variables delegated to the base views” so that I can override what tables get used in the complicated base view, which has a ton of Liquid I don’t want to repeat. There are 4 of these “variable” table references, so I can’t just use the view parameter sql_table_name: whatever in the main view. If there’s a better way to do this, I’m open-ears. The choice of tables are not user-selections, they’re hard-coded.

I found a sort-of “grimy” fix (see below example), but it seems fragile and I’d like to know why I get the error in the first place, or if there’s a better way to make “variable” table references in an extended view. I looked into LookML constants, but they seem to apply at the project-manifest level, so I’m not really sure if they would work here.

Minimal example to re-create the error:

view: source_table {
  derived_table: {
    persist_for: "1 hour"
    sql: --
        SELECT
            'dummy' as dummy
    ;;
  }
}
view: uses_source {
  
  dimension: source_table_name {
    sql:${source_table.SQL_TABLE_NAME};;
    hidden: yes
  }
  
  dimension: select_me_for_error { # <------ Selecting this causes "undefined method inline for nil:NilClass"
    sql: 'this will cause an error' ;;
  }
  
  dimension: select_me_for_fix { # <------ Selecting this fixes "undefined method inline for nil:NilClass"
    sql:${source_table_name};;
  }
  
  derived_table: {
    sql: --
        -- {{source_table_name._sql}}
    ;;
  }
}
explore: uses_source {}
0 2 2,963
2 REPLIES 2

I think what I’m going to end up doing is “mirroring” any PDT’s that I need to reference, like:

view: source_table_mirror {
    derived_table: {
        sql: --
            SELECT
                *
            FROM
                ${source_table.SQL_TABLE_NAME}
        ;;
    }
}

And then reference source_table_mirror in my extended-view “variable” dimensions (with no SQL_TABLE_NAME needed because non-PDT tables seem to always have “simple” naming).

Still a little worried that this causes yet another level of indirection in a rather complicated query, and eventually I’ll start confusing the optimizer… My PDT has various partition_key and cluster_keys, etc., and I don’t know if the “mirrored” table would optimize off of those.

EDIT: Actually, maybe the ${EXTENDED} keyword could work here – will give that a try and post the solution if it works, for anybody else who might run into this type of scenario.

For anybody who might want to do something similar to this, with complicated code in one re-usable “base view”, using “variables” from views that extend the base-view, here is a solution:

view: indirection0a_base {

  derived_table: {
    sql: --
        -- source_table_name (from base view) = {{source_table_name}}
        SELECT
            dummy
        FROM
            {{source_table_name}}
    ;;
  }
}

view: indirection0a_extended {
  extends: [indirection0a_base]

  dimension: select_me_to_test {
    sql: 'dummy' ;;
  }

  derived_table: {
    sql: --
        {% assign source_table_name = "${source_table.SQL_TABLE_NAME}" %}
        -- source_table_name (from extending view):{{source_table_name}}
        ${EXTENDED}
    ;;
  }
}

If you can isolate the part of the code that uses the variable-table stuff to the extended view, then you don’t even need to join source_table to your Explore. If the “complicated / needs to be re-used” part of your code must use source_table in its complicated logic (like me), then you must join source_table into your Explore, even if the main query never pulls from it directly. The Liquid {% assign source_table_name = ... statement above can only “see” source_table if it’s joined-in, and you’ll get a “variable not found” error if you don’t join it. Just do something like this to appease that logic:

explore: indirection0a_extended {
  join: source_table {
    sql:  ;;
    relationship: one_to_one
  }
}

You don’t even need an always_join; the table will get pulled-in just fine whether it’s a PDT or not.

Top Labels in this Space
Top Solution Authors