diff --git a/SQLite.xs b/SQLite.xs index 48f113d..0a3a052 100644 --- a/SQLite.xs +++ b/SQLite.xs @@ -391,6 +391,24 @@ txn_state(SV* dbh, SV *schema = &PL_sv_undef) OUTPUT: RETVAL +static int +error_offset(dbh) + SV *dbh + ALIAS: + DBD::SQLite::db::sqlite_error_offset = 1 + CODE: + { +#if SQLITE_VERSION_NUMBER >= 3038000 + D_imp_dbh(dbh); + RETVAL = sqlite3_error_offset(imp_dbh->db); +#else + RETVAL = -1; +#endif + } + OUTPUT: + RETVAL + + MODULE = DBD::SQLite PACKAGE = DBD::SQLite::st PROTOTYPES: DISABLE diff --git a/lib/DBD/SQLite.pm b/lib/DBD/SQLite.pm index 54077ef..abfb709 100644 --- a/lib/DBD/SQLite.pm +++ b/lib/DBD/SQLite.pm @@ -62,6 +62,7 @@ sub driver { DBD::SQLite::db->install_method('sqlite_db_config'); DBD::SQLite::db->install_method('sqlite_get_autocommit'); DBD::SQLite::db->install_method('sqlite_txn_state'); + DBD::SQLite::db->install_method('sqlite_error_offset'); $methods_are_installed++; } @@ -2431,6 +2432,12 @@ can be imported from DBD::SQLite::Constants. You may pass an optional schema name (usually "main"). If SQLite does not support this function, or if you pass a wrong schema name, -1 is returned. +=head2 $dbh->sqlite_error_offset() + +Returns the byte offset of the start of a problematic input SQL token +or -1 if the most recent error does not reference a specific token in +the input SQL (or DBD::SQLite is built with an older version of SQLite). + =head1 DRIVER FUNCTIONS =head2 DBD::SQLite::compile_options() diff --git a/t/07_error.t b/t/07_error.t index c2b1620..086874d 100644 --- a/t/07_error.t +++ b/t/07_error.t @@ -25,4 +25,12 @@ ok($@, 'Statement 2 generated an error'); is( $DBI::err, 19, '$DBI::err ok' ); like( $DBI::errstr, qr/column a is not unique|UNIQUE constraint failed/, '$DBI::errstr ok' ); +if ($DBD::SQLite::sqlite_version_number && $DBD::SQLite::sqlite_version_number >= 3038000) { + my $sql = 'insert testerror values (1, 5)'; + eval { $dbh->do($sql) }; + my $offset = $dbh->sqlite_error_offset; + ok $offset != -1, "error offset: $offset"; + note substr($sql, 0, $offset) . '<*error*>' . substr($sql, $offset); +} + done_testing;