#!/usr/bin/env perl
use v5.38;
use Benchmark qw(cmpthese);

# Compara _format_sql y _get_query_type antes/despues de cachear regex.
#
# Antes: _format_sql itera 13 keywords, compilando una regex con
# interpolacion en cada iteracion (13 regex compiles por llamada).
# Despues: una sola regex precompilada via state.
#
# Antes: _get_query_type evalua hasta 7 regexes con /i.
# Despues: una regex precompilada con captura.

my $sql = "SELECT u.id, u.name FROM users u JOIN orders o ON o.user_id = u.id WHERE u.active = ? GROUP BY u.id ORDER BY u.id LIMIT 10";

sub format_old {
    my $s = shift;
    my @keywords = qw(SELECT FROM WHERE INSERT UPDATE DELETE JOIN ON GROUP BY HAVING ORDER LIMIT);
    for my $keyword (@keywords) {
        $s =~ s/\b$keyword\b/\n$keyword/g;
    }
    return $s;
}

sub format_new {
    my $s = shift;
    state $kw_re = qr/\b(SELECT|FROM|WHERE|INSERT|UPDATE|DELETE|JOIN|ON|GROUP|BY|HAVING|ORDER|LIMIT)\b/;
    $s =~ s/$kw_re/\n$1/g;
    return $s;
}

sub type_old {
    my $s = shift;
    return 'SELECT' if $s =~ /^\s*SELECT/i;
    return 'INSERT' if $s =~ /^\s*INSERT/i;
    return 'UPDATE' if $s =~ /^\s*UPDATE/i;
    return 'DELETE' if $s =~ /^\s*DELETE/i;
    return 'CREATE' if $s =~ /^\s*CREATE/i;
    return 'ALTER'  if $s =~ /^\s*ALTER/i;
    return 'DROP'   if $s =~ /^\s*DROP/i;
    return 'OTHER';
}

sub type_new {
    my $s = shift;
    state $type_re = qr/^\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP)/i;
    return uc($1) if $s =~ $type_re;
    return 'OTHER';
}

# Smoke
die "format mismatch" if format_old($sql) ne format_new($sql);
die "type mismatch"   if type_old($sql)  ne type_new($sql);

say "=== _format_sql ===";
cmpthese(-3, {
    old => sub { format_old($sql) for 1 .. 1000 },
    new => sub { format_new($sql) for 1 .. 1000 },
});

say "\n=== _get_query_type ===";
my @queries = (
    "SELECT 1",
    "INSERT INTO t VALUES (1)",
    "UPDATE t SET x=1",
    "DELETE FROM t",
    "BEGIN",
);

cmpthese(-3, {
    old => sub { for (1 .. 200) { type_old($_) for @queries } },
    new => sub { for (1 .. 200) { type_new($_) for @queries } },
});
