DBIO-MySQL
view release on metacpan or search on metacpan
lib/DBIO/MySQL/SQLMaker.pm view on Meta::CPAN
my ($target, $source, $attributes) = @_;
my ($sql, @bind) = $self->next::method(@_);
# Extract target table name for self-referencing detection
my $target_name = $self->_extract_target_name($target);
$sql = $self->_wrap_self_referencing_subquery($sql, $target_name) if $target_name;
return ($sql, @bind);
}
sub delete {
my $self = shift;
my ($target, $source, $attributes) = @_;
my ($sql, @bind) = $self->next::method(@_);
# Extract target table name for self-referencing detection
my $target_name = $self->_extract_target_name($target);
$sql = $self->_wrap_self_referencing_subquery($sql, $target_name) if $target_name;
return ($sql, @bind);
}
sub _extract_target_name {
my ($self, $target) = @_;
return unless defined $target;
if (ref $target eq 'SCALAR') {
if ($$target =~ /^ (?:
\` ( [^`]+ ) \` #`
| ( [\w\-]+ )
) $/x
) {
return (defined $1) ? $1 : $2;
}
return; # complex scalar ref, can't deal
}
# For HASH refs (simple result source) or plain strings, return as-is
return ref $target ? undef : $target;
}
#
# Support for MySQL lock clause syntax according to specification
# including updates introduced in MySQL 8.0.1)
# FOR UPDATE | FOR SHARE [OF tbl_name [, tbl_name] ...] [NOWAIT | SKIP LOCKED]
#
my $lock_types = {
update => 'FOR UPDATE',
share => 'FOR SHARE',
};
my $lock_modifiers = {
nowait => 'NOWAIT',
skip_locked => 'SKIP LOCKED'
};
sub _lock_select {
my ($self, $type) = @_;
# Handle hash-based configuration to support new featureset
if (ref $type eq 'HASH') {
my $lock_type = $type->{type};
my $tables = $type->{of};
my $modifier = $type->{modifier};
my $lock_clause = $lock_types->{$lock_type}
|| $self->throw_exception("Unknown SELECT .. FOR type '$lock_type' requested");
# Add OF clause if tables are specified
if ($tables) {
my @table_list = ref $tables eq 'ARRAY' ? @$tables : ($tables);
if (@table_list) {
my $quoted_tables = join(', ',
map { $self->_quote($_) } @table_list
);
$lock_clause .= " OF $quoted_tables";
}
}
# Add modifier if specified
if ($modifier) {
my $mod_sql = $lock_modifiers->{$modifier}
|| $self->throw_exception("Unknown lock modifier '$modifier' requested");
$lock_clause .= " $mod_sql";
}
return " $lock_clause";
}
# Handle simple string types (for backward compatibility)
my $sql = $lock_types->{$type}
|| $self->throw_exception("Unknown SELECT .. FOR type '$type' requested");
return " $sql";
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
DBIO::MySQL::SQLMaker - MySQL-specific SQL generation for DBIO
=head1 VERSION
version 0.900000
=head1 SYNOPSIS
lib/DBIO/MySQL/SQLMaker.pm view on Meta::CPAN
MySQL-specific SQL generation layer for L<DBIO>. Extends L<DBIO::SQLMaker>
with the following MySQL adaptations:
=over 4
=item *
C<INSERT> with no columns emits C<INSERT INTO t () VALUES ()> instead of
the standard C<INSERT INTO t DEFAULT VALUES>, which MySQL does not support.
=item *
Supports C<STRAIGHT_JOIN> as a join type hint via the C<join_type> result
source attribute.
=item *
C<UPDATE> and C<DELETE> statements that reference the modification target
table in a subquery are automatically wrapped in a double subquery to work
around MySQL's restriction against self-referencing in DML.
=item *
Implements MySQL's C<SELECT ... FOR UPDATE / FOR SHARE> locking syntax,
including the C<OF tbl_name>, C<NOWAIT>, and C<SKIP LOCKED> clauses
introduced in MySQL 8.0.1.
=back
=head1 METHODS
=head2 apply_limit
Uses MySQL's C<LIMIT [offset,] rows> syntax instead of the standard
C<LIMIT rows OFFSET offset>.
=head2 insert
Overrides the standard C<INSERT> to emit C<INSERT INTO t () VALUES ()> for
rows with no column values, satisfying MySQL's syntax requirements.
=head2 update
=head2 delete
Overrides the base C<update> and C<delete> methods. When the modification
target table is referenced in a subquery within the same statement (a pattern
MySQL rejects), the affected subquery is automatically re-wrapped in an
additional C<SELECT * FROM (...) `_forced_double_subquery`> layer to satisfy
MySQL's parser.
=head2 _lock_select
Generates the locking clause appended to C<SELECT> statements. Accepts
either a plain string (C<'update'>, C<'share'>) or a hashref
for fine-grained control:
$rs->search({}, { for => { type => 'update', of => ['tbl'], modifier => 'nowait' } });
Valid C<type> values: C<update>, C<share>.
Valid C<modifier> values: C<nowait>, C<skip_locked>.
The C<of> key takes a table name or arrayref of table names.
=seealso
=over 4
=item * L<DBIO::MySQL::Storage> - Storage class that uses this SQL maker
=item * L<DBIO::MySQL> - Schema component entry point
=back
=head1 AUTHOR
DBIO & DBIx::Class Authors
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors
Portions Copyright (C) 2005-2025 DBIx::Class Authors
Based on DBIx::Class, heavily modified.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
( run in 1.002 second using v1.01-cache-2.11-cpan-bbe5e583499 )