Skip to content

Commit

Permalink
Merge branch 'main' into L028_autofix
Browse files Browse the repository at this point in the history
  • Loading branch information
OTooleMichael committed Mar 3, 2022
2 parents 1c06f0c + f1cd4c6 commit 6acc997
Show file tree
Hide file tree
Showing 27 changed files with 1,761 additions and 168 deletions.
6 changes: 4 additions & 2 deletions src/sqlfluff/core/linter/linter.py
Expand Up @@ -914,9 +914,11 @@ def paths_from_path(
# that the ignore file is processed after the sql file.

# Scan for remaining files
for ext in self.config.get("sql_file_exts", default=".sql").split(","):
for ext in (
self.config.get("sql_file_exts", default=".sql").lower().split(",")
):
# is it a sql file?
if fname.endswith(ext):
if fname.lower().endswith(ext):
buffer.append(fpath)

if not ignore_files:
Expand Down
4 changes: 1 addition & 3 deletions src/sqlfluff/dialects/dialect_ansi.py
Expand Up @@ -3374,9 +3374,7 @@ class ExplainStatementSegment(BaseSegment):
Ref("DeleteStatementSegment"),
)

match_grammar = StartsWith("EXPLAIN")

parse_grammar = Sequence(
match_grammar = Sequence(
"EXPLAIN",
explainable_stmt,
)
Expand Down
44 changes: 29 additions & 15 deletions src/sqlfluff/dialects/dialect_bigquery.py
Expand Up @@ -10,28 +10,29 @@

from sqlfluff.core.dialects import load_raw_dialect
from sqlfluff.core.parser import (
AnyNumberOf,
Anything,
BaseSegment,
OneOf,
Ref,
Sequence,
Bracketed,
CodeSegment,
Dedent,
Delimited,
AnyNumberOf,
Indent,
KeywordSegment,
SymbolSegment,
RegexLexer,
StringLexer,
CodeSegment,
Matchable,
NamedParser,
StringParser,
RegexParser,
Nothing,
StartsWith,
OneOf,
OptionallyBracketed,
Indent,
Dedent,
Matchable,
Ref,
RegexLexer,
RegexParser,
SegmentGenerator,
Sequence,
StartsWith,
StringLexer,
StringParser,
SymbolSegment,
)
from sqlfluff.core.parser.segments.base import BracketedSegment
from sqlfluff.dialects.dialect_bigquery_keywords import (
Expand Down Expand Up @@ -132,7 +133,7 @@
),
# Add a Full equivalent which also allow keywords
NakedIdentifierSegmentFull=RegexParser(
r"[A-Z0-9_]*[A-Z][A-Z0-9_]*",
r"[A-Z_][A-Z0-9_]*",
CodeSegment,
name="naked_identifier_all",
type="identifier",
Expand All @@ -158,6 +159,19 @@


bigquery_dialect.replace(
# Override to allow _01 type identifiers which are valid in BigQuery
# The strange regex here it to make sure we don't accidentally match numeric
# literals. We also use a regex to explicitly exclude disallowed keywords.
NakedIdentifierSegment=SegmentGenerator(
# Generate the anti template from the set of reserved keywords
lambda dialect: RegexParser(
r"[A-Z_][A-Z0-9_]*",
CodeSegment,
name="naked_identifier",
type="identifier",
anti_template=r"^(" + r"|".join(dialect.sets("reserved_keywords")) + r")$",
)
),
FunctionContentsExpressionGrammar=OneOf(
Sequence(
Ref("ExpressionSegment"),
Expand Down
8 changes: 4 additions & 4 deletions src/sqlfluff/dialects/dialect_postgres.py
Expand Up @@ -1097,9 +1097,7 @@ class ExplainStatementSegment(BaseSegment):

type = "explain_statement"

match_grammar = ansi_dialect.get_segment("ExplainStatementSegment").match_grammar

parse_grammar = Sequence(
match_grammar = Sequence(
"EXPLAIN",
OneOf(
Sequence(
Expand All @@ -1113,7 +1111,9 @@ class ExplainStatementSegment(BaseSegment):
Bracketed(Delimited(Ref("ExplainOptionSegment"))),
optional=True,
),
ansi_dialect.get_segment("ExplainStatementSegment").explainable_stmt,
ansi_dialect.get_segment(
"ExplainStatementSegment",
).explainable_stmt,
)


Expand Down
201 changes: 118 additions & 83 deletions src/sqlfluff/dialects/dialect_snowflake.py
Expand Up @@ -120,13 +120,6 @@
name="warehouse_size",
type="warehouse_size",
),
DoubleQuotedLiteralSegment=NamedParser(
"double_quote",
CodeSegment,
name="quoted_literal",
type="literal",
trim_chars=('"',),
),
ValidationModeOptionSegment=RegexParser(
r"'?RETURN_(?:\d+_ROWS|ERRORS|ALL_ERRORS)'?",
CodeSegment,
Expand Down Expand Up @@ -218,6 +211,16 @@
name="file_type",
type="file_type",
),
GroupByContentsGrammar=Delimited(
OneOf(
Ref("ColumnReferenceSegment"),
# Can `GROUP BY 1`
Ref("NumericLiteralSegment"),
# Can `GROUP BY coalesce(col, 1)`
Ref("ExpressionSegment"),
),
terminator=OneOf("ORDER", "LIMIT", "HAVING", "QUALIFY", "WINDOW"),
),
)

snowflake_dialect.replace(
Expand Down Expand Up @@ -254,6 +257,8 @@
),
JoinLikeClauseGrammar=Sequence(
AnySetOf(
Ref("ChangesClauseSegment"),
Ref("ConnectByClauseSegment"),
Ref("FromAtExpressionSegment"),
Ref("FromBeforeExpressionSegment"),
Ref("FromPivotExpressionSegment"),
Expand Down Expand Up @@ -282,6 +287,32 @@
optional=True,
),
TemporaryTransientGrammar=OneOf(Ref("TemporaryGrammar"), "TRANSIENT"),
BaseExpressionElementGrammar=OneOf(
# Allow use of CONNECT_BY_ROOT pseudo-columns.
# https://docs.snowflake.com/en/sql-reference/constructs/connect-by.html#:~:text=Snowflake%20supports%20the%20CONNECT_BY_ROOT,the%20Examples%20section%20below.
Sequence("CONNECT_BY_ROOT", Ref("ColumnReferenceSegment")),
Ref("LiteralGrammar"),
Ref("BareFunctionSegment"),
Ref("IntervalExpressionSegment"),
Ref("FunctionSegment"),
Ref("ColumnReferenceSegment"),
Ref("ExpressionSegment"),
),
QuotedLiteralSegment=OneOf(
# https://docs.snowflake.com/en/sql-reference/data-types-text.html#string-constants
NamedParser(
"single_quote",
CodeSegment,
name="quoted_literal",
type="literal",
),
NamedParser(
"dollar_quote",
CodeSegment,
name="quoted_literal",
type="literal",
),
),
)

# Add all Snowflake keywords
Expand Down Expand Up @@ -397,6 +428,32 @@
)


@snowflake_dialect.segment()
class ConnectByClauseSegment(BaseSegment):
"""A `CONNECT BY` clause.
https://docs.snowflake.com/en/sql-reference/constructs/connect-by.html
"""

type = "connectby_clause"
match_grammar = Sequence(
"START",
"WITH",
Ref("ExpressionSegment"),
"CONNECT",
"BY",
Delimited(
Sequence(
Ref.keyword("PRIOR", optional=True),
Ref("ColumnReferenceSegment"),
Ref("EqualsSegment"),
Ref.keyword("PRIOR", optional=True),
Ref("ColumnReferenceSegment"),
),
),
)


@snowflake_dialect.segment(replace=True)
class GroupByClauseSegment(BaseSegment):
"""A `GROUP BY` clause like in `SELECT`.
Expand All @@ -416,86 +473,19 @@ class GroupByClauseSegment(BaseSegment):
"GROUP",
"BY",
Indent,
Delimited(
OneOf(
Ref("ColumnReferenceSegment"),
# Can `GROUP BY 1`
Ref("NumericLiteralSegment"),
# Can `GROUP BY coalesce(col, 1)`
Ref("ExpressionSegment"),
Ref("CubeRollupClauseSegment"),
Ref("GroupingSetsClauseSegment"),
OneOf(
Sequence(
OneOf("CUBE", "ROLLUP", Sequence("GROUPING", "SETS")),
Bracketed(
Ref("GroupByContentsGrammar"),
),
),
terminator=OneOf("ORDER", "LIMIT", "HAVING", "QUALIFY", "WINDOW"),
Ref("GroupByContentsGrammar"),
),
Dedent,
)


@snowflake_dialect.segment()
class CubeRollupClauseSegment(BaseSegment):
"""`CUBE` / `ROLLUP` clause within the `GROUP BY` clause."""

type = "cube_rollup_clause"
match_grammar = StartsWith(
OneOf("CUBE", "ROLLUP"),
terminator=OneOf(
"HAVING",
"QUALIFY",
Sequence("ORDER", "BY"),
"LIMIT",
Ref("SetOperatorSegment"),
),
)
parse_grammar = Sequence(
OneOf("CUBE", "ROLLUP"),
Bracketed(
Ref("GroupingExpressionList"),
),
)


@snowflake_dialect.segment()
class GroupingSetsClauseSegment(BaseSegment):
"""`GROUPING SETS` clause within the `GROUP BY` clause."""

type = "grouping_sets_clause"
match_grammar = StartsWith(
Sequence("GROUPING", "SETS"),
terminator=OneOf(
"HAVING",
"QUALIFY",
Sequence("ORDER", "BY"),
"LIMIT",
Ref("SetOperatorSegment"),
),
)
parse_grammar = Sequence(
"GROUPING",
"SETS",
Bracketed(
Delimited(
Ref("CubeRollupClauseSegment"),
Ref("GroupingExpressionList"),
Bracketed(), # Allows empty parentheses
)
),
)


@snowflake_dialect.segment()
class GroupingExpressionList(BaseSegment):
"""Grouping expression list within `CUBE` / `ROLLUP` `GROUPING SETS`."""

type = "grouping_expression_list"
match_grammar = Delimited(
OneOf(
Bracketed(Delimited(Ref("ExpressionSegment"))),
Ref("ExpressionSegment"),
)
)


@snowflake_dialect.segment(replace=True)
class ValuesClauseSegment(BaseSegment):
"""A `VALUES` clause like in `INSERT`."""
Expand Down Expand Up @@ -523,7 +513,7 @@ class FunctionDefinitionGrammar(BaseSegment):
type = "function_definition"
match_grammar = Sequence(
"AS",
OneOf(Ref("QuotedLiteralSegment"), Ref("DollarQuotedLiteralSegment")),
Ref("QuotedLiteralSegment"),
Sequence(
"LANGUAGE",
# Not really a parameter, but best fit for now.
Expand Down Expand Up @@ -659,6 +649,51 @@ class TableAliasExpressionSegment(BaseSegment):
)


@snowflake_dialect.segment()
class ChangesClauseSegment(BaseSegment):
"""A `CHANGES` clause.
https://docs.snowflake.com/en/sql-reference/constructs/changes.html
"""

type = "changes_clause"
match_grammar = Sequence(
"CHANGES",
Bracketed(
"INFORMATION",
Ref("ParameterAssignerSegment"),
OneOf("DEFAULT", "APPEND_ONLY"),
),
OneOf(
Sequence(
"AT",
Bracketed(
OneOf("TIMESTAMP", "OFFSET", "STATEMENT"),
Ref("ParameterAssignerSegment"),
Ref("ExpressionSegment"),
),
),
Sequence(
"BEFORE",
Bracketed(
"STATEMENT",
Ref("ParameterAssignerSegment"),
Ref("ExpressionSegment"),
),
),
),
Sequence(
"END",
Bracketed(
OneOf("TIMESTAMP", "OFFSET", "STATEMENT"),
Ref("ParameterAssignerSegment"),
Ref("ExpressionSegment"),
),
optional=True,
),
)


@snowflake_dialect.segment()
class FromAtExpressionSegment(BaseSegment):
"""An AT expression."""
Expand Down Expand Up @@ -2957,7 +2992,7 @@ class ExplainStatementSegment(
https://docs.snowflake.com/en/sql-reference/sql/explain.html
"""

parse_grammar = Sequence(
match_grammar = Sequence(
"EXPLAIN",
Sequence(
"USING",
Expand Down

0 comments on commit 6acc997

Please sign in to comment.