Open carlobehtash opened 1 month ago
@carlobehtash - I do most of the development for SQLFluff on a Windows machine but I'm struggling to recreate this bug. You're not the first person to report something similar though, so I'd love to get to the bottom of what's causing it.
There are a few things that would really help debug this, if you're able to provide them:
Line N, Position X: Found unparsable section:
& Length of templated file mismatch with final slice: Y != Z
, what are the actual values for N
, X
, Y
& Z
?\r\n
or \n
for newlines). Could you confirm which style of newlines the file in question uses (LF
or CRLF
- if you're using VSCode it will be shown in the bottom right of the screen) - and even better would be to try changing the newline character from one to the other and see if that resolves the issue.What would also be useful would be a set of verbose logs for linting just that file, so if you could run sqlfluff lint /my/file.sql -vvvvvv
for a minimal file which exhibits the bug that would be very helpful. If you're right that this always happens, then select * from {{ ref('some_other_table') }}
should be enough to trigger it.
If anyone else is watching this issue who has the same problem - more data here would be better to pin down what's going on and be able to recreate the bug.
@carlobehtash - I am facing similar issue and this is the verbose logs
==== sqlfluff ====
sqlfluff: 3.2.5 python: 3.11.9
implementation: cpython verbosity: 6
dialect: databricks templater: dbt
dbt: =1.9.0-b2
rules: all
== Raw Config:
core:
dialect: databricks
disable_noqa: False
encoding: autodetect
exclude_rules: L016,L031,L034,L026,L009
fix_even_unparsable:False
ignore: []
ignore_templated_areas:True
large_file_skip_byte_limit:0
large_file_skip_char_limit:0
max_line_length: 80
nocolor: False
output_line_length: 80
processes: 1
render_variant_limit:1
rules: all
runaway_limit: 10
sql_file_exts: .sql,.sql.j2,.dml,.ddl
templater: dbt
verbose: 6
warn_unused_ignores:False
warnings: []
indentation:
allow_implicit_indents:True
ignore_comment_lines:False
indent_unit: space
indented_ctes: False
indented_joins: False
indented_on_contents:True
indented_then: True
indented_then_contents:True
indented_using_on: True
skip_indentation_in:script_content
tab_space_size: 2
template_blocks_indent:True
trailing_comments: before
layout:
type:
alias_expression:
align_scope: bracketed
align_within: select_clause
spacing_before: align
array_accessor:
spacing_before: touch:inline
array_type:
spacing_within: touch:inline
assignment_operator:
line_position: leading
spacing_within: touch
binary_operator:
line_position: leading
spacing_within: touch
bracketed_arguments:
spacing_before: touch:inline
casting_operator:
spacing_after: touch:inline
spacing_before: touch
colon:
spacing_before: touch
colon_delimiter:
spacing_after: touch
spacing_before: touch
comma:
line_position: trailing
spacing_before: touch
comment:
spacing_after: any
spacing_before: any
common_table_expression:
spacing_within: single:inline
comparison_operator:
line_position: leading
spacing_within: touch
dot:
spacing_after: touch
spacing_before: touch
end_angle_bracket:
spacing_before: touch
end_bracket:
spacing_before: touch
end_of_file:
spacing_before: touch
end_square_bracket:
spacing_before: touch
from_clause:
line_position: alone
function_contents:
spacing_before: touch:inline
function_name:
spacing_within: touch:inline
function_parameter_list:
spacing_before: touch:inline
groupby_clause:
line_position: alone
having_clause:
line_position: alone
join_clause:
line_position: alone
limit_clause:
line_position: alone
match_condition:
spacing_within: touch:inline
numeric_literal:
spacing_within: touch:inline
object_reference:
spacing_within: touch:inline
orderby_clause:
line_position: leading
path_segment:
spacing_within: touch
pattern_expression:
spacing_within: any
placeholder:
spacing_after: any
spacing_before: any
select_clause:
line_position: alone
semi_structured_expression:
spacing_before: touch:inline
spacing_within: touch:inline
set_operator:
line_position: alone:strict
sign_indicator:
spacing_after: touch:inline
sized_array_type:
spacing_within: touch
slash:
spacing_after: any
spacing_before: any
slice:
spacing_after: touch
spacing_before: touch
sql_conf_option:
spacing_within: touch
sqlcmd_operator:
spacing_before: touch
start_angle_bracket:
spacing_after: touch
start_bracket:
spacing_after: touch
start_square_bracket:
spacing_after: touch
statement_terminator:
line_position: trailing
spacing_before: touch
struct_type:
spacing_within: touch:inline
template_loop:
spacing_after: any
spacing_before: any
tilde:
spacing_after: touch:inline
typed_array_literal:
spacing_within: touch
typed_struct_literal:
spacing_within: touch
where_clause:
line_position: alone
rules:
allow_scalar: True
single_table_references:consistent
unquoted_identifiers_policy:all
aliasing.column:
aliasing: explicit
aliasing.forbid:
force_enable: False
aliasing.length:
min_alias_length: 4
aliasing.table:
aliasing: explicit
aliasing.unused:
alias_case_check: dialect
ambiguous.column_references:
group_by_and_order_by_style:consistent
ambiguous.join:
fully_qualify_join_types:inner
capitalisation.functions:
extended_capitalisation_policy:upper
capitalisation.identifiers:
extended_capitalisation_policy:lower
capitalisation.keywords:
capitalisation_policy:upper
capitalisation.literals:
capitalisation_policy:upper
capitalisation.types:
extended_capitalisation_policy:upper
convention.blocked_words:
match_source: False
convention.casting_style:
preferred_type_casting_style:consistent
convention.count_rows:
prefer_count_0: False
prefer_count_1: False
convention.not_equal:
preferred_not_equal_style:consistent
convention.quoted_literals:
force_enable: False
preferred_quoted_literal_style:consistent
convention.select_trailing_comma:
select_clause_trailing_comma:forbid
convention.terminator:
multiline_newline: False
require_final_semicolon:False
layout.long_lines:
ignore_comment_clauses:False
ignore_comment_lines:False
layout.select_targets:
wildcard_policy: single
references.consistent:
force_enable: False
references.from:
force_enable: False
references.keywords:
unquoted_identifiers_policy:aliases
references.qualification:
references.quoting:
case_sensitive: True
prefer_quoted_identifiers:False
prefer_quoted_keywords:False
references.special_chars:
additional_allowed_characters:['.','(',')','-','<=>']
allow_space_in_identifier:True
quoted_identifiers_policy:all
unquoted_identifiers_policy:all
structure.join_condition_order:
preferred_first_table_in_join_clause:earlier
structure.subquery:
forbid_subquery_in: join
templater:
unwrap_wrapped_queries:True
dbt:
project_dir: ./
==== readout ====
=== [dbt templater] Sorting Nodes...
INFO Rendering String [dbt] (src\models\marts\facts\tmp.sql)
=== [dbt templater] Compiling dbt project...
=== [dbt templater] Project Compiled.
DEBUG _find_node for path 'D:\\path\\to\\model\\tmp.sql' returned object of type <class 'dbt.contracts.graph.nodes.ModelNode'>.
DEBUG Trailing newline count in source dbt model: 0
DEBUG Raw SQL before compile: '{{ "SELECT \'lorem\' AS text;" }}'
DEBUG Node raw SQL: '{{ "SELECT \'lorem\' AS text;" }}'
DEBUG Node compiled SQL: "SELECT 'lorem' AS text;"
INFO Slicing File Template
DEBUG Raw String: '{{ "SELECT \'lorem\' AS text;" }}'
INFO Rendered 1 variants
INFO Parse Rendered. Lexing Variant 0
INFO LEXING RAW (D:\path\to\model\tmp.sql)
INFO Elements to Segments.
DEBUG 0: TemplateElement(raw='{', template_slice=slice(0, 1, None), matcher=<StringLexer: start_curly_bracket>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='templated', source_slice=slice(0, 31, None), templated_slice=slice(0, 31, None))
DEBUG Contained templated slice.
DEBUG 1: TemplateElement(raw='{', template_slice=slice(1, 2, None), matcher=<StringLexer: start_curly_bracket>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='templated', source_slice=slice(0, 31, None), templated_slice=slice(0, 31, None))
DEBUG Contained templated slice.
DEBUG 2: TemplateElement(raw=' ', template_slice=slice(2, 3, None), matcher=<RegexLexer: whitespace>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='templated', source_slice=slice(0, 31, None), templated_slice=slice(0, 31, None))
DEBUG Contained templated slice.
DEBUG 3: TemplateElement(raw='"SELECT \'lorem\' AS text;"', template_slice=slice(3, 28, None), matcher=<RegexLexer: double_quote>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='templated', source_slice=slice(0, 31, None), templated_slice=slice(0, 31, None))
DEBUG Contained templated slice.
DEBUG 4: TemplateElement(raw=' ', template_slice=slice(28, 29, None), matcher=<RegexLexer: whitespace>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='templated', source_slice=slice(0, 31, None), templated_slice=slice(0, 31, None))
DEBUG Contained templated slice.
DEBUG 5: TemplateElement(raw='}', template_slice=slice(29, 30, None), matcher=<StringLexer: end_curly_bracket>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='templated', source_slice=slice(0, 31, None), templated_slice=slice(0, 31, None))
DEBUG Contained templated slice.
DEBUG 6: TemplateElement(raw='}', template_slice=slice(30, 31, None), matcher=<StringLexer: end_curly_bracket>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='templated', source_slice=slice(0, 31, None), templated_slice=slice(0, 31, None))
DEBUG Contained templated slice.
INFO Lexed segments: ['{', '{', ' ', '"SELECT \'lorem\' AS text;"', ' ', '}', '}', '']
INFO Parse Rendered. Parsing Variant 0
INFO Root Match:
Match (None): slice(0, 0, None)
INFO
###
#
# Parsed Tree:
#
###
INFO
[L: 1, P: 1] |file:
[L: 1, P: 1] | unparsable: !! Expected: "<Delimited: [<Ref: 'StatementSegment'>]>"
[L: 1, P: 1] | start_curly_bracket: '{'
[L: 1, P: 1] | start_curly_bracket: '{'
[L: 1, P: 1] | whitespace: ' '
[L: 1, P: 1] | double_quote: '"SELECT \'lorem\' AS text;"'
[L: 1, P: 1] | whitespace: ' '
[L: 1, P: 1] | end_curly_bracket: '}'
[L: 1, P: 1] | end_curly_bracket: '}'
[L: 1, P: 32] | [META] end_of_file:
INFO Found unparsable segment...
INFO [L: 1, P: 1] |unparsable: !! Expected: "<Delimited: [<Ref: 'StatementSegment'>]>"
[L: 1, P: 1] | start_curly_bracket: '{'
[L: 1, P: 1] | start_curly_bracket: '{'
[L: 1, P: 1] | whitespace: ' '
[L: 1, P: 1] | double_quote: '"SELECT \'lorem\' AS text;"'
[L: 1, P: 1] | whitespace: ' '
[L: 1, P: 1] | end_curly_bracket: '}'
[L: 1, P: 1] | end_curly_bracket: '}'
INFO Parse Rendered. Variant 0. Lex in 0.01600000006146729. Parse in 0.0.
INFO lint_parsed - linting root variant (src\models\marts\facts\tmp.sql)
== [src\models\marts\facts\tmp.sql] LINTING (AL01, AL02, AL03, AL04, AL05, AL06, AL08, AL09, AM01, AM02, AM03, AM04, AM05, AM06, AM07, CP01, CP02, CP03, CP04, CP05, CV01, CV02, CV03, CV04, CV05, CV06, CV07, CV08, CV09, CV10, CV11, JJ01, LT01, LT02, LT03, LT04, LT06, LT07, LT08, LT09, LT10, LT11, LT13, RF02, RF03, RF04, RF05, RF06, ST01, ST02, ST03, ST04, ST05, ST07, ST08, ST09, TQ01)
INFO
Entering linter phase main, loop 1/1
DEBUG [JJ01] Tag found @ source index 0: '{{ "SELECT \'lorem\' AS text;" }}'
DEBUG [JJ01] Tag string segments: '{{' | ' ' | '"SELECT \'lorem\' AS text;"' | ' ' | '}}' @ 0 + 0
DEBUG * Respacing: '' @ None
DEBUG Inline case. Constraints: single <-> single.
DEBUG Inserting Single Whitespace.
DEBUG Not Detected existing fix. Creating new
DEBUG Modified result buffer: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 1]) '{'>+1F)]
DEBUG New Results: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 1]) '{'>+1F)]
DEBUG * Respacing: ' ' @ [L: 1, P: 1]
DEBUG Inline case. Constraints: single <-> single.
DEBUG * Respacing: ' ' @ [L: 1, P: 1]
DEBUG Inline case. Constraints: single <-> single.
DEBUG * Respacing: '' @ None
DEBUG Inline case. Constraints: single <-> single.
DEBUG Inserting Single Whitespace.
DEBUG Not Detected existing fix. Creating new
DEBUG Modified result buffer: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 1]) '{'>+1F), LintResult(Expected single whitespace between end curly bracket and end curly bracket.: <CodeSegment: ([L: 1, P: 1]) '}'>+1F)]
DEBUG New Results: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 1]) '{'>+1F), LintResult(Expected single whitespace between end curly bracket and end curly bracket.: <CodeSegment: ([L: 1, P: 1]) '}'>+1F)]
DEBUG * Respacing: '' @ None
INFO * Discarding fixes that touch templated code: [<LintFix: create_after start_curly_bracket@[L: 1, P: 1] create:' '>]
INFO Fix skipped due to parent of anchor not passing filter: [<FileSegment: ([L: 1, P: 1])>, <UnparsableSegment: ([L:
1, P: 1])>]
INFO * Discarding fixes that touch templated code: [<LintFix: create_after end_curly_bracket@[L: 1, P: 1] create:' '>]
INFO Fix skipped due to parent of anchor not passing filter: [<FileSegment: ([L: 1, P: 1])>, <UnparsableSegment: ([L:
1, P: 1])>]
INFO # Evaluating indents.
DEBUG # Revise skipped source lines.
DEBUG # Revise templated lines.
DEBUG Sorted Group UUIDs: []
DEBUG # Revise comment lines.
DEBUG # Evaluate lines for indentation.
INFO
###
#
# Fixed Tree:
#
###
INFO
[L: 1, P: 1] |file:
[L: 1, P: 1] | unparsable: !! Expected: "<Delimited: [<Ref: 'StatementSegment'>]>"
[L: 1, P: 1] | start_curly_bracket: '{'
[L: 1, P: 1] | start_curly_bracket: '{'
[L: 1, P: 1] | whitespace: ' '
[L: 1, P: 1] | double_quote: '"SELECT \'lorem\' AS text;"'
[L: 1, P: 1] | whitespace: ' '
[L: 1, P: 1] | end_curly_bracket: '}'
[L: 1, P: 1] | end_curly_bracket: '}'
[L: 1, P: 32] | [META] end_of_file:
== [src\models\marts\facts\tmp.sql] FAIL
L: 1 | P: 1 | PRS | Line 1, Position 1: Found unparsable section: '{{
| "SELECT \'lorem\' AS text;" }}'
WARNING: Parsing errors found and dialect is set to 'databricks'. Have you configured your dialect correctly?
==== summary ====
files: 1 violations: 1
clean files: 0 unclean files: 1
avg per file: 1.00 unclean rate: 100%
status: FAIL
All Finished π π!
With a ref macro
(.venv) D:\path\to\project>sqlfluff lint --templater dbt src\models\marts\facts\tmp.sql -vvvvvv
==== sqlfluff ====
sqlfluff: 3.2.5 python: 3.11.9
implementation: cpython verbosity: 6
dialect: databricks templater: dbt
dbt: =1.9.0-b2
rules: all
== Raw Config:
core:
dialect: databricks
disable_noqa: False
encoding: autodetect
exclude_rules: L016,L031,L034,L026,L009
fix_even_unparsable:False
ignore: []
ignore_templated_areas:True
large_file_skip_byte_limit:0
large_file_skip_char_limit:0
max_line_length: 80
nocolor: False
output_line_length: 80
processes: 1
render_variant_limit:1
rules: all
runaway_limit: 10
sql_file_exts: .sql,.sql.j2,.dml,.ddl
templater: dbt
verbose: 6
warn_unused_ignores:False
warnings: []
indentation:
allow_implicit_indents:True
ignore_comment_lines:False
indent_unit: space
indented_ctes: False
indented_joins: False
indented_on_contents:True
indented_then: True
indented_then_contents:True
indented_using_on: True
skip_indentation_in:script_content
tab_space_size: 2
template_blocks_indent:True
trailing_comments: before
layout:
type:
alias_expression:
align_scope: bracketed
align_within: select_clause
spacing_before: align
array_accessor:
spacing_before: touch:inline
array_type:
spacing_within: touch:inline
assignment_operator:
line_position: leading
spacing_within: touch
binary_operator:
line_position: leading
spacing_within: touch
bracketed_arguments:
spacing_before: touch:inline
casting_operator:
spacing_after: touch:inline
spacing_before: touch
colon:
spacing_before: touch
colon_delimiter:
spacing_after: touch
spacing_before: touch
comma:
line_position: trailing
spacing_before: touch
comment:
spacing_after: any
spacing_before: any
common_table_expression:
spacing_within: single:inline
comparison_operator:
line_position: leading
spacing_within: touch
dot:
spacing_after: touch
spacing_before: touch
end_angle_bracket:
spacing_before: touch
end_bracket:
spacing_before: touch
end_of_file:
spacing_before: touch
end_square_bracket:
spacing_before: touch
from_clause:
line_position: alone
function_contents:
spacing_before: touch:inline
function_name:
spacing_within: touch:inline
function_parameter_list:
spacing_before: touch:inline
groupby_clause:
line_position: alone
having_clause:
line_position: alone
join_clause:
line_position: alone
limit_clause:
line_position: alone
match_condition:
spacing_within: touch:inline
numeric_literal:
spacing_within: touch:inline
object_reference:
spacing_within: touch:inline
orderby_clause:
line_position: leading
path_segment:
spacing_within: touch
pattern_expression:
spacing_within: any
placeholder:
spacing_after: any
spacing_before: any
select_clause:
line_position: alone
semi_structured_expression:
spacing_before: touch:inline
spacing_within: touch:inline
set_operator:
line_position: alone:strict
sign_indicator:
spacing_after: touch:inline
sized_array_type:
spacing_within: touch
slash:
spacing_after: any
spacing_before: any
slice:
spacing_after: touch
spacing_before: touch
sql_conf_option:
spacing_within: touch
sqlcmd_operator:
spacing_before: touch
start_angle_bracket:
spacing_after: touch
start_bracket:
spacing_after: touch
start_square_bracket:
spacing_after: touch
statement_terminator:
line_position: trailing
spacing_before: touch
struct_type:
spacing_within: touch:inline
template_loop:
spacing_after: any
spacing_before: any
tilde:
spacing_after: touch:inline
typed_array_literal:
spacing_within: touch
typed_struct_literal:
spacing_within: touch
where_clause:
line_position: alone
rules:
allow_scalar: True
single_table_references:consistent
unquoted_identifiers_policy:all
aliasing.column:
aliasing: explicit
aliasing.forbid:
force_enable: False
aliasing.length:
min_alias_length: 4
aliasing.table:
aliasing: explicit
aliasing.unused:
alias_case_check: dialect
ambiguous.column_references:
group_by_and_order_by_style:consistent
ambiguous.join:
fully_qualify_join_types:inner
capitalisation.functions:
extended_capitalisation_policy:upper
capitalisation.identifiers:
extended_capitalisation_policy:lower
capitalisation.keywords:
capitalisation_policy:upper
capitalisation.literals:
capitalisation_policy:upper
capitalisation.types:
extended_capitalisation_policy:upper
convention.blocked_words:
match_source: False
convention.casting_style:
preferred_type_casting_style:consistent
convention.count_rows:
prefer_count_0: False
prefer_count_1: False
convention.not_equal:
preferred_not_equal_style:consistent
convention.quoted_literals:
force_enable: False
preferred_quoted_literal_style:consistent
convention.select_trailing_comma:
select_clause_trailing_comma:forbid
convention.terminator:
multiline_newline: False
require_final_semicolon:False
layout.long_lines:
ignore_comment_clauses:False
ignore_comment_lines:False
layout.select_targets:
wildcard_policy: single
references.consistent:
force_enable: False
references.from:
force_enable: False
references.keywords:
unquoted_identifiers_policy:aliases
references.qualification:
references.quoting:
case_sensitive: True
prefer_quoted_identifiers:False
prefer_quoted_keywords:False
references.special_chars:
additional_allowed_characters:['.','(',')','-','<=>']
allow_space_in_identifier:True
quoted_identifiers_policy:all
unquoted_identifiers_policy:all
structure.join_condition_order:
preferred_first_table_in_join_clause:earlier
structure.subquery:
forbid_subquery_in: join
templater:
unwrap_wrapped_queries:True
dbt:
project_dir: D:\path\to\project\./
jinja:
apply_dbt_builtins: True
library_path: D:\path\to\project\dbt_packages
load_macros_from_path:D:\path\to\project\./src/macros/
==== readout ====
=== [dbt templater] Sorting Nodes...
INFO Rendering String [dbt] (src\models\marts\facts\tmp.sql)
=== [dbt templater] Compiling dbt project...
=== [dbt templater] Project Compiled.
DEBUG _find_node for path 'D:\\path\\to\\model\\tmp.sql' returned object of type <class 'dbt.contracts.graph.nodes.ModelNode'>.
DEBUG Trailing newline count in source dbt model: 0
DEBUG Raw SQL before compile: "SELECT * FROM {{ ref('int_user_joined') }}"
DEBUG Node raw SQL: "SELECT * FROM {{ ref('int_user_joined') }}"
DEBUG Node compiled SQL: 'SELECT * FROM `catalog_name`.`schema_name`.`int_user_joined`'
INFO Slicing File Template
DEBUG Raw String: "SELECT * FROM {{ ref('int_user_joined') }}"
INFO Rendered 1 variants
INFO Parse Rendered. Lexing Variant 0
INFO LEXING RAW (D:\path\to\model\tmp.sql)
INFO Elements to Segments.
DEBUG 0: TemplateElement(raw='SELECT', template_slice=slice(0, 6, None), matcher=<RegexLexer: word>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='literal', source_slice=slice(0, 14, None), templated_slice=slice(0, 14, None))
DEBUG Consuming whole from literal. Existing Consumed: 0
DEBUG 1: TemplateElement(raw=' ', template_slice=slice(6, 7, None), matcher=<RegexLexer: whitespace>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='literal', source_slice=slice(0, 14, None), templated_slice=slice(0, 14, None))
DEBUG Consuming whole from literal. Existing Consumed: 0
DEBUG 2: TemplateElement(raw='*', template_slice=slice(7, 8, None), matcher=<StringLexer: star>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='literal', source_slice=slice(0, 14, None), templated_slice=slice(0, 14, None))
DEBUG Consuming whole from literal. Existing Consumed: 0
DEBUG 3: TemplateElement(raw=' ', template_slice=slice(8, 9, None), matcher=<RegexLexer: whitespace>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='literal', source_slice=slice(0, 14, None), templated_slice=slice(0, 14, None))
DEBUG Consuming whole from literal. Existing Consumed: 0
DEBUG 4: TemplateElement(raw='FROM', template_slice=slice(9, 13, None), matcher=<RegexLexer: word>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='literal', source_slice=slice(0, 14, None), templated_slice=slice(0, 14, None))
DEBUG Consuming whole from literal. Existing Consumed: 0
DEBUG 5: TemplateElement(raw=' ', template_slice=slice(13, 14, None), matcher=<RegexLexer: whitespace>). [tfs_idx = 0]
DEBUG 0: TemplatedFileSlice(slice_type='literal', source_slice=slice(0, 14, None), templated_slice=slice(0, 14, None))
DEBUG Consuming whole from literal. Existing Consumed: 0
DEBUG 6: TemplateElement(raw='{', template_slice=slice(14, 15, None), matcher=<StringLexer: start_curly_bracket>). [tfs_idx = 1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 7: TemplateElement(raw='{', template_slice=slice(15, 16, None), matcher=<StringLexer: start_curly_bracket>). [tfs_idx = 1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 8: TemplateElement(raw=' ', template_slice=slice(16, 17, None), matcher=<RegexLexer: whitespace>). [tfs_idx = 1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 9: TemplateElement(raw='ref', template_slice=slice(17, 20, None), matcher=<RegexLexer: word>). [tfs_idx = 1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 10: TemplateElement(raw='(', template_slice=slice(20, 21, None), matcher=<StringLexer: start_bracket>). [tfs_idx
= 1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 11: TemplateElement(raw="'int_user_joined'", template_slice=slice(21, 38, None), matcher=<RegexLexer: single_quote>). [tfs_idx = 1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 12: TemplateElement(raw=')', template_slice=slice(38, 39, None), matcher=<StringLexer: end_bracket>). [tfs_idx =
1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 13: TemplateElement(raw=' ', template_slice=slice(39, 40, None), matcher=<RegexLexer: whitespace>). [tfs_idx = 1]DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 14: TemplateElement(raw='}', template_slice=slice(40, 41, None), matcher=<StringLexer: end_curly_bracket>). [tfs_idx = 1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
DEBUG 15: TemplateElement(raw='}', template_slice=slice(41, 42, None), matcher=<StringLexer: end_curly_bracket>). [tfs_idx = 1]
DEBUG 1: TemplatedFileSlice(slice_type='templated', source_slice=slice(14, 42, None), templated_slice=slice(14, 42, None))
DEBUG Contained templated slice.
INFO Lexed segments: ['SELECT', ' ', '*', ' ', 'FROM', ' ', '{', '{', ' ', 'ref', '(', "'int_user_joined'", ')', ' ', '}', '}', '']
INFO Parse Rendered. Parsing Variant 0
INFO Root Match:
Match (<class 'sqlfluff.dialects.dialect_databricks.StatementSegment'>): slice(0, 16, None)
+Match (<class 'sqlfluff.dialects.dialect_sparksql.SelectStatementSegment'>): slice(0, 16, None)
+Match (<class 'sqlfluff.dialects.dialect_sparksql.SelectClauseSegment'>): slice(0, 3, None)
+2: <class 'sqlfluff.core.parser.segments.meta.Indent'>
+3: <class 'sqlfluff.core.parser.segments.meta.Dedent'>
+Match (<class 'sqlfluff.core.parser.segments.keyword.KeywordSegment'>): slice(0, 1, None)
-instance_types: ('keyword',)
+Match (<class 'sqlfluff.dialects.dialect_ansi.SelectClauseElementSegment'>): slice(2, 3, None)
+Match (<class 'sqlfluff.dialects.dialect_sparksql.WildcardExpressionSegment'>): slice(2, 3, None)
+Match (<class 'sqlfluff.dialects.dialect_ansi.WildcardIdentifierSegment'>): slice(2, 3, None)
+Match (<class 'sqlfluff.core.parser.segments.common.SymbolSegment'>): slice(2, 3, None)
-instance_types: ('star',)
+Match (<class 'sqlfluff.core.parser.segments.base.UnparsableSegment'>): slice(4, 16, None)
-expected: 'Nothing here.'
INFO
###
#
# Parsed Tree:
#
###
INFO
[L: 1, P: 1] |file:
[L: 1, P: 1] | statement:
[L: 1, P: 1] | select_statement:
[L: 1, P: 1] | select_clause:
[L: 1, P: 1] | keyword: 'SELECT'
[L: 1, P: 7] | whitespace: ' '
[L: 1, P: 8] | [META] indent:
[L: 1, P: 8] | select_clause_element:
[L: 1, P: 8] | wildcard_expression:
[L: 1, P: 8] | wildcard_identifier:
[L: 1, P: 8] | star: '*'
[L: 1, P: 9] | [META] dedent:
[L: 1, P: 9] | whitespace: ' '
[L: 1, P: 10] | unparsable: !! Expected: 'Nothing here.'
[L: 1, P: 10] | word: 'FROM'
[L: 1, P: 14] | whitespace: ' '
[L: 1, P: 15] | start_curly_bracket: '{'
[L: 1, P: 15] | start_curly_bracket: '{'
[L: 1, P: 15] | whitespace: ' '
[L: 1, P: 15] | word: 'ref'
[L: 1, P: 15] | start_bracket: '('
[L: 1, P: 15] | single_quote: "'int_user_joined'"
[L: 1, P: 15] | end_bracket: ')'
[L: 1, P: 15] | whitespace: ' '
[L: 1, P: 15] | end_curly_bracket: '}'
[L: 1, P: 15] | end_curly_bracket: '}'
[L: 1, P: 43] | [META] end_of_file:
INFO Found unparsable segment...
INFO [L: 1, P: 10] |unparsable: !! Expected: 'Nothing here.'
[L: 1, P: 10] | word: 'FROM'
[L: 1, P: 14] | whitespace: ' '
[L: 1, P: 15] | start_curly_bracket: '{'
[L: 1, P: 15] | start_curly_bracket: '{'
[L: 1, P: 15] | whitespace: ' '
[L: 1, P: 15] | word: 'ref'
[L: 1, P: 15] | start_bracket: '('
[L: 1, P: 15] | single_quote: "'int_user_joined'"
[L: 1, P: 15] | end_bracket: ')'
[L: 1, P: 15] | whitespace: ' '
[L: 1, P: 15] | end_curly_bracket: '}'
[L: 1, P: 15] | end_curly_bracket: '}'
INFO Parse Rendered. Variant 0. Lex in 0.014999999897554517. Parse in 0.01600000006146729.
INFO lint_parsed - linting root variant (src\models\marts\facts\tmp.sql)
== [src\models\marts\facts\tmp.sql] LINTING (AL01, AL02, AL03, AL04, AL05, AL06, AL08, AL09, AM01, AM02, AM03, AM04, AM05, AM06, AM07, CP01, CP02, CP03, CP04, CP05, CV01, CV02, CV03, CV04, CV05, CV06, CV07, CV08, CV09, CV10, CV11, JJ01, LT01, LT02, LT03, LT04, LT06, LT07, LT08, LT09, LT10, LT11, LT13, RF02, RF03, RF04, RF05, RF06, ST01, ST02, ST03, ST04, ST05, ST07, ST08, ST09, TQ01)
INFO
Entering linter phase main, loop 1/1
DEBUG [AM04] Analyzing query: SELECT * FROM {{ ref('int_user_joined') }}
DEBUG [AM04] Query target "SELECT * FROM {{ ref('int_user_joined') }}" has no targets. Generating warning.
INFO [AM04] !! Violation Found: 'Query produces an unknown number of result columns.'
INFO [CP01] _handle_segment: <KeywordSegment: ([L: 1, P: 1]) 'SELECT'>, keyword
DEBUG [CP01] Selected 'capitalisation_policy': 'upper' from options ['upper', 'lower', 'capitalise']
DEBUG [CP01] Refuted cases after segment 'SELECT': {'pascal', 'snake', 'camel', 'capitalise', 'lower'}
DEBUG [CP01] Consistent capitalization upper, returning with memory: {'refuted_cases': {'pascal', 'snake', 'camel', 'capitalise', 'lower'}}
DEBUG [JJ01] Tag found @ source index 14: "{{ ref('int_user_joined') }}"
DEBUG [JJ01] Tag string segments: '{{' | ' ' | "ref('int_user_joined')" | ' ' | '}}' @ 14 + 0
DEBUG * Respacing: ' ' @ [L: 1, P: 7]
DEBUG Inline case. Constraints: single <-> single.
DEBUG * Respacing: ' ' @ [L: 1, P: 9]
DEBUG Inline case. Constraints: single <-> single.
DEBUG * Respacing: ' ' @ [L: 1, P: 14]
DEBUG Inline case. Constraints: single <-> single.
DEBUG * Respacing: '' @ None
DEBUG Inline case. Constraints: single <-> single.
DEBUG Inserting Single Whitespace.
DEBUG Not Detected existing fix. Creating new
DEBUG Modified result buffer: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 15]) '{'>+1F)]
DEBUG New Results: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 15]) '{'>+1F)]
DEBUG * Respacing: ' ' @ [L: 1, P: 15]
DEBUG Inline case. Constraints: single <-> single.
DEBUG * Respacing: '' @ None
DEBUG Inline case. Constraints: single <-> single.
DEBUG Inserting Single Whitespace.
DEBUG Not Detected existing fix. Creating new
DEBUG Modified result buffer: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 15]) '{'>+1F), LintResult(Expected single whitespace between word and start bracket.: <CodeSegment: ([L: 1, P: 15]) '('>+1F)]
DEBUG New Results: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 15]) '{'>+1F), LintResult(Expected single whitespace between word and start bracket.: <CodeSegment: ([L:
1, P: 15]) '('>+1F)]
DEBUG * Respacing: '' @ None
DEBUG Inline case. Constraints: touch <-> single.
DEBUG New Results: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 15]) '{'>+1F), LintResult(Expected single whitespace between word and start bracket.: <CodeSegment: ([L:
1, P: 15]) '('>+1F)]
DEBUG * Respacing: '' @ None
DEBUG Inline case. Constraints: single <-> touch.
DEBUG New Results: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 15]) '{'>+1F), LintResult(Expected single whitespace between word and start bracket.: <CodeSegment: ([L:
1, P: 15]) '('>+1F)]
DEBUG * Respacing: ' ' @ [L: 1, P: 15]
DEBUG Inline case. Constraints: single <-> single.
DEBUG * Respacing: '' @ None
DEBUG Inline case. Constraints: single <-> single.
DEBUG Inserting Single Whitespace.
DEBUG Not Detected existing fix. Creating new
DEBUG Modified result buffer: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 15]) '{'>+1F), LintResult(Expected single whitespace between word and start bracket.: <CodeSegment: ([L: 1, P: 15]) '('>+1F), LintResult(Expected single whitespace between end curly bracket and end curly bracket.: <CodeSegment: ([L: 1, P: 15]) '}'>+1F)]
DEBUG New Results: [LintResult(Expected single whitespace between start curly bracket and start curly bracket.: <CodeSegment: ([L: 1, P: 15]) '{'>+1F), LintResult(Expected single whitespace between word and start bracket.: <CodeSegment: ([L:
1, P: 15]) '('>+1F), LintResult(Expected single whitespace between end curly bracket and end curly bracket.: <CodeSegment: ([L: 1, P: 15]) '}'>+1F)]
DEBUG * Respacing: '' @ None
INFO * Discarding fixes that touch templated code: [<LintFix: create_after start_curly_bracket@[L: 1, P: 15] create:' '>]
INFO Fix skipped due to parent of anchor not passing filter: [<FileSegment: ([L: 1, P: 1])>, <StatementSegment: ([L:
1, P: 1])>, <SelectStatementSegment: ([L: 1, P: 1])>, <UnparsableSegment: ([L: 1, P: 10])>]
INFO * Discarding fixes that touch templated code: [<LintFix: create_after word@[L: 1, P: 15] create:' '>]
INFO Fix skipped due to parent of anchor not passing filter: [<FileSegment: ([L: 1, P: 1])>, <StatementSegment: ([L:
1, P: 1])>, <SelectStatementSegment: ([L: 1, P: 1])>, <UnparsableSegment: ([L: 1, P: 10])>]
INFO * Discarding fixes that touch templated code: [<LintFix: create_after end_curly_bracket@[L: 1, P: 15] create:' '>]
INFO Fix skipped due to parent of anchor not passing filter: [<FileSegment: ([L: 1, P: 1])>, <StatementSegment: ([L:
1, P: 1])>, <SelectStatementSegment: ([L: 1, P: 1])>, <UnparsableSegment: ([L: 1, P: 10])>]
INFO # Evaluating indents.
DEBUG # Revise skipped source lines.
DEBUG # Revise templated lines.
DEBUG Sorted Group UUIDs: []
DEBUG # Revise comment lines.
DEBUG # Evaluate lines for indentation.
INFO ## Evaluate Rendered Line #1 [source line #1]. idx=1:21.
DEBUG Line Content: ["' '", "'*'", "' '", "'FROM'", "' '", "'{'", "''", "'{'", "' '", "'ref'", "''", "'('", "''", '"\'int_user_joined\'"', "''", "')'", "' '", "'}'", "''", "'}'"]
DEBUG Indent Line: IndentLine(iib=0, ipts=[iPt@1(1, 0, 0, None, False, ()), iPt@3(-1, -1, 1, None, False, (1,)), iPt@21(0, 0, 0, None, False, ())])
DEBUG Forced Indents: []
DEBUG Imbalanced Indent Locs: []
DEBUG Desired Indent Calculation: IB: 0, RUI: [], UIL: (), iII: 1, iIT: 0. = 0
INFO [LT09] Target at index 3 is already on a single line.
INFO
###
#
# Fixed Tree:
#
###
INFO
[L: 1, P: 1] |file:
[L: 1, P: 1] | statement:
[L: 1, P: 1] | select_statement:
[L: 1, P: 1] | select_clause:
[L: 1, P: 1] | keyword: 'SELECT'
[L: 1, P: 7] | whitespace: ' '
[L: 1, P: 8] | [META] indent:
[L: 1, P: 8] | select_clause_element:
[L: 1, P: 8] | wildcard_expression:
[L: 1, P: 8] | wildcard_identifier:
[L: 1, P: 8] | star: '*'
[L: 1, P: 9] | [META] dedent:
[L: 1, P: 9] | whitespace: ' '
[L: 1, P: 10] | unparsable: !! Expected: 'Nothing here.'
[L: 1, P: 10] | word: 'FROM'
[L: 1, P: 14] | whitespace: ' '
[L: 1, P: 15] | start_curly_bracket: '{'
[L: 1, P: 15] | start_curly_bracket: '{'
[L: 1, P: 15] | whitespace: ' '
[L: 1, P: 15] | word: 'ref'
[L: 1, P: 15] | start_bracket: '('
[L: 1, P: 15] | single_quote: "'int_user_joined'"
[L: 1, P: 15] | end_bracket: ')'
[L: 1, P: 15] | whitespace: ' '
[L: 1, P: 15] | end_curly_bracket: '}'
[L: 1, P: 15] | end_curly_bracket: '}'
[L: 1, P: 43] | [META] end_of_file:
== [src\models\marts\facts\tmp.sql] FAIL
L: 1 | P: 10 | PRS | Line 1, Position 10: Found unparsable section: "FROM {{
| ref('int_user_joined') }}"
WARNING: Parsing errors found and dialect is set to 'databricks'. Have you configured your dialect correctly?
==== summary ====
files: 1 violations: 1
clean files: 0 unclean files: 1
avg per file: 1.00 unclean rate: 100%
status: FAIL
All Finished π π!
Search before asking
What Happened
When trying to sqlfluff lint/fix/parse on a Windows machine with the templater set to dbt, basic Jinja (ex.
{{ source('project', 'table') }}
) gives one of the following errors, depending on the specific case:Line N, Position X: Found unparsable section:
Length of templated file mismatch with final slice: X != Y
The behaviour only occurs on Windows machines.
Expected Behaviour
No errors and any linting violations are caught.
Observed Behaviour
sqlfluff-templater-dbt is unable to parse Jinja
How to reproduce
Try linting/fixing/parsing a model:
Dialect
BigQuery
Version
dbt-bigquery==1.6.9 sqlfluff==3.0.6 sqlfluff-templater-dbt==3.0.6
(upgrading to 3.2.0 doesn't fix)
Configuration
Are you willing to work on and submit a PR to address the issue?
Code of Conduct