Example #1
0
def test__linter__raises_malformed_noqa():
    """A badly formatted noqa gets raised as a parsing error."""
    lntr = Linter()
    result = lntr.lint_string_wrapped("select 1 --noqa missing semicolon")

    with pytest.raises(SQLParseError):
        result.check_tuples()
Example #2
0
def lint(
    sql: str,
    dialect: str = "ansi",
    rules: Optional[List[str]] = None,
    exclude_rules: Optional[List[str]] = None,
    config_path: Optional[str] = None,
) -> List[Dict[str, Any]]:
    """Lint a SQL string.

    Args:
        sql (:obj:`str`): The SQL to be linted.
        dialect (:obj:`str`, optional): A reference to the dialect of the SQL
            to be linted. Defaults to `ansi`.
        rules (:obj:`Optional[List[str]`, optional): A list of rule
            references to lint for. Defaults to None.
        exclude_rules (:obj:`Optional[List[str]`, optional): A list of rule
            references to avoid linting for. Defaults to None.
        config_path (:obj:`Optional[str]`, optional): A path to a .sqlfluff config.
            Defaults to None.

    Returns:
        :obj:`List[Dict[str, Any]]` for each violation found.
    """
    cfg = get_simple_config(
        dialect=dialect,
        rules=rules,
        exclude_rules=exclude_rules,
        config_path=config_path,
    )
    linter = Linter(config=cfg)

    result = linter.lint_string_wrapped(sql)
    result_records = result.as_records()
    # Return just the violations for this file
    return [] if not result_records else result_records[0]["violations"]
Example #3
0
def test__rules__std_L062_raised() -> None:
    """L062 is raised for use of blocked words with correct error message."""
    sql = "SELECT MYOLDFUNCTION(col1) FROM deprecated_table;\n"
    cfg = FluffConfig(overrides={"dialect": "ansi"})
    cfg.set_value(
        config_path=["rules", "L062", "blocked_words"],
        val="myoldfunction,deprecated_table",
    )
    linter = Linter(config=cfg)
    result_records = linter.lint_string_wrapped(sql).as_records()
    result = result_records[0]["violations"]

    assert len(result) == 2
    assert result[0]["description"] == "Use of blocked word 'MYOLDFUNCTION'."
    assert result[1]["description"] == "Use of blocked word 'deprecated_table'."
Example #4
0
def fix(
    sql: str,
    dialect: str = "ansi",
    rules: Optional[List[str]] = None,
    exclude_rules: Optional[List[str]] = None,
    config_path: Optional[str] = None,
    fix_even_unparsable: Optional[bool] = None,
) -> str:
    """Fix a SQL string.

    Args:
        sql (:obj:`str`): The SQL to be fixed.
        dialect (:obj:`str`, optional): A reference to the dialect of the SQL
            to be fixed. Defaults to `ansi`.
        rules (:obj:`Optional[List[str]`, optional): A subset of rule
            references to fix for. Defaults to None.
        exclude_rules (:obj:`Optional[List[str]`, optional): A subset of rule
            references to avoid fixing for. Defaults to None.
        config_path (:obj:`Optional[str]`, optional): A path to a .sqlfluff config.
            Defaults to None.

    Returns:
        :obj:`str` for the fixed SQL if possible.
    """
    cfg = get_simple_config(
        dialect=dialect,
        rules=rules,
        exclude_rules=exclude_rules,
        config_path=config_path,
    )
    linter = Linter(config=cfg)

    result = linter.lint_string_wrapped(sql, fix=True)
    if fix_even_unparsable is None:
        fix_even_unparsable = cfg.get("fix_even_unparsable")
    should_fix = True
    if not fix_even_unparsable:
        # If fix_even_unparsable wasn't set, check for templating or parse
        # errors and suppress fixing if there were any.
        _, num_filtered_errors = result.count_tmp_prs_errors()
        if num_filtered_errors > 0:
            should_fix = False
    if should_fix:
        sql = result.paths[0].files[0].fix_string()[0]
    return sql
Example #5
0
def fix(sql, dialect="ansi", rules=None):
    """Fix a sql string or file.

    Args:
        sql (:obj:`str` or file-like object): The sql to be linted
            either as a string or a subclass of :obj:`TextIOBase`.
        dialect (:obj:`str`, optional): A reference to the dialect of the sql
            to be linted. Defaults to `ansi`.
        rules (:obj:`str` or iterable of :obj:`str`, optional): A subset of rule
            reference to lint for.

    Returns:
        :obj:`str` for the fixed sql if possible.
    """
    sql = _unify_str_or_file(sql)
    linter = Linter(dialect=dialect, rules=rules)

    result = linter.lint_string_wrapped(sql, fix=True)
    fixed_string = result.paths[0].files[0].fix_string()[0]
    return fixed_string
Example #6
0
def lint(sql, dialect="ansi", rules=None):
    """Lint a sql string or file.

    Args:
        sql (:obj:`str` or file-like object): The sql to be linted
            either as a string or a subclass of :obj:`TextIOBase`.
        dialect (:obj:`str`, optional): A reference to the dialect of the sql
            to be linted. Defaults to `ansi`.
        rules (:obj:`str` or iterable of :obj:`str`, optional): A subset of rule
            reference to lint for.

    Returns:
        :obj:`list` of :obj:`dict` for each violation found.
    """
    sql = _unify_str_or_file(sql)
    linter = Linter(dialect=dialect, rules=rules)

    result = linter.lint_string_wrapped(sql)
    result_records = result.as_records()
    # Return just the violations for this file
    return [] if not result_records else result_records[0]["violations"]
Example #7
0
def test__rules__std_L007_before():
    """Verify that L007 returns the correct error message when before is used."""
    sql = """
        SELECT
            a,
            b
        FROM foo
        WHERE
            a = 1
            AND b = 2
    """
    config = FluffConfig(
        configs={"rules": {"L007": {"operator_new_lines": "before"}}},
        overrides={"dialect": "ansi"},
    )
    # The sqlfluff.lint API doesn't allow us to pass config so need to do what it does
    linter = Linter(config=config)
    result_records = linter.lint_string_wrapped(sql).as_records()
    result = result_records[0]["violations"]
    assert "L007" in [r["code"] for r in result]
    assert before_description in [r["description"] for r in result]
Example #8
0
def test__rules__std_L007_after():
    """Verify orrect error message when after is explicitly used."""
    sql = """
        SELECT
            a,
            b
        FROM foo
        WHERE
            a = 1 AND
            b = 2
    """
    config = FluffConfig(
        configs={"rules": {
            "L007": {
                "operator_new_lines": "after"
            }
        }})
    # The sqlfluff.lint API doesn't allow us to pass config so need to do what it does
    linter = Linter(config=config)
    result_records = linter.lint_string_wrapped(sql).as_records()
    result = result_records[0]["violations"]
    assert "L007" in [r["code"] for r in result]
    assert after_description in [r["description"] for r in result]