Skip to content

feat: DBI column_info, $^S fix, __LINE__ interpolation fix#418

Merged
fglock merged 10 commits intomasterfrom
feature/dbi-column-info-autocommit
Apr 1, 2026
Merged

feat: DBI column_info, $^S fix, __LINE__ interpolation fix#418
fglock merged 10 commits intomasterfrom
feature/dbi-column-info-autocommit

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 1, 2026

Summary

Continues DBIx::Class Phase 5 work. Three fixes that improve the test pass rate from 78% to 88%+.

DBI improvements (DBI.java, DBI.pm)

  • column_info() via SQLite PRAGMA table_info() — preserves original type case (JDBC uppercases type names, breaking DBIC type detection)
  • Metadata sth blessingtable_info, column_info, primary_key_info, foreign_key_info, type_info results now blessed into DBI with proper attributes
  • Literal transaction SQL interceptionBEGIN/COMMIT/ROLLBACK routed through JDBC API (setAutoCommit/commit/rollback) instead of executing SQL directly, fixing SQLite JDBC autocommit conflicts
  • AutoCommit state tracking$dbh->{AutoCommit} updated when transaction SQL is detected
  • prepare_cached per-dbh cache — changed from global %CACHED_STATEMENTS to per-dbh $dbh->{CachedKids}, preventing cross-connection cache pollution with :memory: databases

$^S fix (WarnDie.java)

  • $^S now correctly reports 1 inside $SIG{__DIE__} when require fails in eval {}
  • Previously reported 0 (top-level) because evalDepth was decremented before catchEval() called the handler
  • Fixes t/00describe_environment.t which uses $^S to distinguish eval-guarded optional requires from real crashes

__LINE__ interpolation fix (CoreOperatorResolver.java, StringDoubleQuoted.java, Parser.java)

  • __LINE__ inside @{[expr]} in double-quoted strings and qr// now returns the correct source line
  • Previously returned the line of the enclosing statement start due to inner sub-parser sharing the outer errorUtil cache
  • Fixes t/106dbic_carp.t tests 2-3 which depend on __LINE__ inside qr// matching actual source lines

DBIx::Class test results

  • Before: 51/65 active tests passing (78%)
  • After: 62/68 active tests passing (91%)
  • t/64db.t: 2/4 → 4/4 real tests
  • t/752sqlite.t: ~11/34 → 34/34 real tests
  • t/00describe_environment.t: crash → fully passing
  • t/106dbic_carp.t: 1/3 → 3/3 real tests

Test plan

  • make passes (all unit tests)
  • $^S verified correct for: die in eval, require fail in eval, top-level die
  • __LINE__ in @{[]} matches Perl 5 in strings and qr//
  • t/64db.t, t/752sqlite.t, t/00describe_environment.t, t/106dbic_carp.t verified

Generated with Devin

fglock and others added 10 commits April 1, 2026 15:27
…re_cached

- Implement column_info() using SQLite PRAGMA table_info() to preserve
  original type case (JDBC uppercases type names, breaking DBIC tests)
- Bless metadata result sets (table_info, column_info, etc.) into DBI
  class with proper Type/Executed/FetchHashKeyName attributes
- Intercept literal BEGIN/COMMIT/ROLLBACK SQL in execute() and use JDBC
  API (setAutoCommit/commit/rollback) instead of executing SQL directly,
  fixing SQLite JDBC autocommit conflicts
- Track AutoCommit state changes when literal transaction SQL is detected
- Fix prepare_cached to use per-dbh CachedKids hash instead of global
  cache, preventing cross-connection cache pollution with :memory: DBs
- Handle metadata sth execute() gracefully (no PreparedStatement)
- Support PRAGMA pre-fetched rows in fetchrow_hashref

DBIx::Class test results: 60/68 active tests pass (88%, was 78%)
- t/64db.t: 4/4 real tests pass (was 2/4)
- t/752sqlite.t: 34/34 real tests pass (was ~11/34)

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…s in eval

When require fails inside eval {}, the __DIE__ handler now sees $^S=1
(inside eval) instead of incorrectly seeing $^S=0 (top-level). The bug
was that evalDepth was decremented by the eval catch block before
catchEval() invoked the handler. Fixed by temporarily incrementing
evalDepth around the handler call in catchEval().

This unblocks t/00describe_environment.t in DBIx::Class which uses
$^S to distinguish eval-guarded optional requires from real crashes.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…number

When __LINE__ appeared inside @{[expr]} in double-quoted strings or qr//,
it returned the line number from the start of the enclosing statement
instead of the actual line. This was caused by the inner sub-parser
sharing the outer errorUtil which uses a forward-only cache.

Fixed by:
- Adding baseLineNumber field to Parser for string sub-parsers
- Setting it from the outer source position in StringDoubleQuoted
- Using it in CoreOperatorResolver to compute __LINE__ by counting
  inner newlines from the base

This fixes t/106dbic_carp.t tests 2-3 in DBIx::Class which depend on
__LINE__ inside qr// matching the actual source line.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- execute_for_fetch now tracks error count and stores [$sth->err,
  $sth->errstr, $sth->state] in tuple_status on failure (matching
  DBI 1.647 behavior)
- After the loop, dies with error count if RaiseError is on
- execute() now sets err/errstr/state on both sth and dbh (was dbh only)
- Clears sth error state before each execute call

Fixes t/100populate.t test 2 (execute_for_fetch exception detection).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Updated test results after fixing $^S, __LINE__ interpolation, and
execute_for_fetch error propagation. Added new "Must Fix" entries for
JDBC error message format, SQL formatting differences, and bind
parameter attribute handling.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
In Perl 5, lexical 'no warnings "redefine"' takes precedence over
the global -w flag ($^W). PerlOnJava was checking $^W with a simple
OR, causing subroutine redefinition warnings even inside no-warnings
blocks. Now checks isWarningDisabled("redefine") first, matching
Perl 5 behavior.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…lation

When ASM's Frame.merge() crashes on methods with extremely high fan-in
(e.g. Sub::Quote-generated subs with 600+ jumps to a single label),
EmitterMethodCreator throws InterpreterFallbackException. However, the
top-level compileToExecutable() in PerlLanguageProvider didn't catch this
exception type, causing the compilation to fail entirely instead of
falling back to the interpreter.

Add explicit catch for InterpreterFallbackException in compileToExecutable()
that returns the pre-built interpreted code from the exception. This fixes
DBIx::Class tests that use Sub::Quote (e.g. t/88result_set_column.t).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Two fixes for DBIx::Class compatibility:

1. Implement MODIFY_CODE_ATTRIBUTES call for subroutine attributes.
   When a sub is declared with attributes (sub foo : Attr { }),
   Perl calls MODIFY_CODE_ATTRIBUTES($package, \&code, @attrs) at
   compile time. This was not implemented, causing DBIx::Class
   ResultSetManager and any module using code attributes to fail.
   Fixes t/40resultsetmanager.t (5/5 planned tests now pass).

2. Fix ROLLBACK TO SAVEPOINT being intercepted as full ROLLBACK.
   DBI.java transaction control interceptor matched any SQL starting
   with ROLLBACK, including ROLLBACK TO SAVEPOINT. This caused
   savepoint operations to incorrectly reset autocommit.
   Fixes t/752sqlite.t (171/172 planned tests now pass).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
When an @inc hook returns a CODE reference (line-reader sub), Perl
repeatedly calls it - the sub sets $_ to each line and returns true
for more data, or false to stop. This pattern is used by PAR and
similar module loaders.

Previously only filehandle, scalar ref, and array ref returns from
@inc hooks were handled. Now CODE ref returns are properly processed
by calling the sub in a loop and accumulating lines from $_.

Fixes t/90ensure_class_loaded.t tests 14 and 17 (27/28 now pass).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- 68/314 test programs fully passing, 93.7% individual test pass rate
- Documented fixes: -w/redefine, InterpreterFallbackException, MODIFY_CODE_ATTRIBUTES,
  ROLLBACK TO SAVEPOINT, @inc CODE hooks
- Updated remaining failures and next steps list

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock merged commit b4dfccb into master Apr 1, 2026
2 checks passed
@fglock fglock deleted the feature/dbi-column-info-autocommit branch April 1, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant