I am having some trouble with DBD-Oracle, when an SQL-statement has some problem and DBD-oracle inserts marker <*> at the error-offset via sv_insert.
With setting NLS_LANG=.AL32UTF8, the error-offset coming from Oracle should be interpreted in unicode-characters but sv_insert works in byte mode.
So I'd like to know if there is some sv_insert_utf8 variant hidden somewhere. Or perhaps some sv_substr_utf8 function would do as well.
Edit: the usage of sv_insert can be seen here: https://github.com/perl5-dbi/DBD-Oracle/blob/master/oci8.c#L943
Meantime I've hacked a half-finished solution:
if (nls_charset==al32utf8) { /* */
parse_error_offset= sv_pos_u2b_flags(sqlsv, parse_error_offset, NULL, SV_GMAGIC|SV_CONST_RETURN);
}
Demonstration of the problem in YaSql-Fx:
> select 'arvizturo tukorfurogep' from duale;
select 'arvizturo tukorfurogep' from duale
*
ORA-00942: table or view does not exist (DBD ERROR: error possibly near <*> indicator at char 37 in 'select 'arvizturo tukorfurogep' from <*>duale')
> select 'árvíztűrő tükörfúrógép' from duale;
select 'árvíztűrő tükörfúrógép' from duale
*
ORA-00942: table or view does not exist (DBD ERROR: error possibly near <*> indicator at char 37 in 'select 'árvíztűrő tükörfúróg\xFFFD<*>\xFFFDp' from duale')
In the second example the <*> marker has been inserted into an utf8 sequence, resulting \xFFFD<*>\xFFFD
Edit: This version seems working
{
D_imp_dbh_from_sth;
int utf8_is_implied = CSFORM_IMPLIES_UTF8(imp_dbh, SQLCS_IMPLICIT);
if (utf8_is_implied) {
parse_error_offset= sv_pos_u2b_flags(sqlsv, parse_error_offset, NULL, SV_GMAGIC|SV_CONS
}
}
https://github.com/lzsiga/DBD-Oracle/commit/3aaf6d206cf5d4b3b40ac87660774e004040d152
Edit: Bad news: actually, the server returns byte-offset, interpreted according to NLS_CHARACTERSET. Which is not known by DBD-Oracle. But if it were known, conversion between NLS_LANG and NLS_CHARACTERSET might be non-trivial (just think of UTFE(872)).