squawk-linter 2.50.0

Linter for Postgres migrations & SQL
Documentation
use rustc_hash::FxHashSet;

use squawk_syntax::{ast, identifier::Identifier};

use crate::Linter;

pub(crate) fn is_not_valid_int_type(
    ty: &ast::Type,
    invalid_type_names: &FxHashSet<Identifier>,
) -> bool {
    match ty {
        ast::Type::ArrayType(array_type) => {
            if let Some(ty) = array_type.ty() {
                is_not_valid_int_type(&ty, invalid_type_names)
            } else {
                false
            }
        }
        ast::Type::PercentType(_) => false,
        ast::Type::PathType(path_type) => {
            let Some(ty_name) = path_type
                .path()
                .and_then(|x| x.segment())
                .and_then(|x| x.name_ref())
                .map(|x| x.text().to_string())
            else {
                return false;
            };
            let name = Identifier::new(ty_name.as_str());
            invalid_type_names.contains(&name)
        }
        ast::Type::CharType(_) => false,
        ast::Type::BitType(_) => false,
        ast::Type::DoubleType(_) => false,
        ast::Type::TimeType(_) => false,
        ast::Type::IntervalType(_) => false,
        ast::Type::ExprType(_) => false,
    }
}

pub(crate) fn check_not_allowed_types(
    ctx: &mut Linter,
    file: &ast::SourceFile,
    check_ty: impl Fn(&mut Linter, Option<ast::Type>),
) {
    for stmt in file.stmts() {
        match stmt {
            ast::Stmt::CreateTable(create_table) => {
                if let Some(table_arg_list) = create_table.table_arg_list() {
                    for arg in table_arg_list.args() {
                        if let ast::TableArg::Column(column) = arg {
                            check_ty(ctx, column.ty());
                        }
                    }
                }
            }
            ast::Stmt::AlterTable(alter_table) => {
                for action in alter_table.actions() {
                    match action {
                        ast::AlterTableAction::AddColumn(add_column) => {
                            check_ty(ctx, add_column.ty());
                        }
                        ast::AlterTableAction::AlterColumn(alter_column) => {
                            if let Some(ast::AlterColumnOption::SetType(set_type)) =
                                alter_column.option()
                            {
                                check_ty(ctx, set_type.ty());
                            }
                        }
                        _ => (),
                    }
                }
            }
            _ => (),
        }
    }
}