A substr csodaja

TL;DR: https://github.com/lzsiga/yasql-fx/blob/main/ReadMeFx.TXT
https://github.com/lzsiga/yasql-fx/blob/main/test/test0001.sh
https://github.com/perl5-dbi/DBD-Oracle/issues/171

Utólag nyilván ez is egyszerű és világos lesz, csak még most van egy kis furcsaság (perl/yasql/substr/utf8), nevezetesen a string a substr hatásara meghosszabbodni látszik, 36 hosszúról 38 hosszúra; a két extra karakter közül az első egy x'00'.


        ----+----1----+----2----+----3----+-
substr('000000000000000000000000010000009397'(is_utf8=1),0,39)=
       '000000000000000000000000010000009397^@7'(is_utf8=1)

Hozzászólások

 if you assign something longer than LENGTH, the string will grow to accommodate

Szerkesztve: 2024. 03. 01., p – 10:16

Nyilván a megkönnyítés kedvéért a perl illetékes source-jába (pp.c), a <stdio.h> nincs beemelve, viszont valamilyen csodás define-ok vannak érvényben az fprintf-re és a stderr-re, a következő végtelenül elegáns módszerrel debuggolunk:

extern struct _IO_FILE *debfile __asm__("stderr"); extern void DEB(struct _IO_FILE *f, const char *fmt, ...) __asm__("fprintf");
...
DEB(debfile, "%s:%s:%d tmps='%s' utf8_curlen=%ld curlen=%ld\n", __FILE__, __func__, __LINE__, tmps, (long)utf8_curlen, (long)curlen);

Lett is egy ilyen:

                               ----+----1----+----2----+----3----+-
pp.c:Perl_pp_substr:3299 tmps='000000000000000000000000010000009397' utf8_curlen=38 curlen=36

If OFFSET and LENGTH specify a substring that is partly outside the string, only the part within the string is returned. If the substring is beyond either end of the string, substr returns the undefined value and produces a warning.

 

Ez a derék yasql szépen sorban kéri a rekordokat a szervertől, mindegyiket méretre akarja vágni substr-vel (39-re, ami a maximum is), ennek során jutunk el ebbe a Perl_pp_substr-be, ahol, úgy tűnik, az utf8_curlen "örökre vasalva" van, szemben a curlen-nel, ami változik.

Off: Nem tudom mondtam-e már, hogy milyen jó dolog a függvény bemenő paraméterét munkaváltozónak használni, nagyon megkönnyíti, hogy a függvény végére debugkiírást tegyünk.

utf8.c:Perl_utf8_length


   2354     while (s < e) {
   2355         s += UTF8SKIP(s);
   2356         len++;
   2357     }

Nem akarom elkiabálni, de mintha lenne egy cache, ami meggyorsítja az utf8_strlen kiszámítását. Mondjuk igaz, optimalizációs szempontból gyorsan kapni rossz eredményt hatékonyabb, mint lassan kapni jó eredményt.

Szerkesztve: 2024. 03. 01., p – 22:17

Na szóval van egy Perl_sv_setpvn meg egy Perl_sv_setpvn_mg. A kettő közötti különbség a SvSETMAGIC (aminek a magja a Perl_mg_set).

Namostan az a nagy kérdésem, hogy vajon a Perl_sv_setpvn-t nem kellett-e volna deprekálni, és egységesen a Perl_sv_setpvn_mg-t hívni helyette?

Off: kezdem azt hinni, hogy azok az ihletett csodaprogramozók (avagy rockstar-coders), akik az ilyen `magic` dolgokat csinálják [nem ém nevezem így, a source-ban van benne], akkor tennék a legjobbat, ha elkerülnék a számítógépeknek még a környékét is.

Szerkesztve: 2024. 03. 05., k – 12:56

Ez most csak egy kis érdekesség: a ;vesszőpont a kommentben megzavarja a programot

Input:

-- this test uses NCHAR;
-- the result depends on NLS_NCHAR_CHARACTERSET (server-side) and NLS_NCHAR (client-side)

Output:

ORA-00900: invalid SQL statement (DBD ERROR: error possibly near <*>
indicator at char 23 in '-- this test uses NCHAR<*>')

Szerk: a csodaprogramozó a lexikális elemzést helyettesítette egy regex-szel (itt a 1149-es sortól). Köszönjük, Emese!