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()
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"]
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'."
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
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
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"]
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]
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]