Skip to content

Instantly share code, notes, and snippets.

@kiwiroy
Last active January 17, 2017 00:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiwiroy/fa0c737ff3f298cb064e554505bc4495 to your computer and use it in GitHub Desktop.
Save kiwiroy/fa0c737ff3f298cb064e554505bc4495 to your computer and use it in GitHub Desktop.
dbd::csv and text::csv unreferenced scalar

Reproduce

Steps to reproduce:

cpanm --installdeps .

prove .

Using perlbrew to test multiple perls.

Attempt to free unreferenced scalar: SV 0x28c6628 during global destruction.

The following perls exhibit this behaviour:

  • 5.24.0

The following perls do not exhibit this behaviour:

  • 5.20.3
  • 5.22.2
./dbd-csv.t ... 2/? # Records
# a: alpha, b: beta has 3 observations
#       9 8 7
#       comment: soup
# a: alpha, b: bravo has 1 observations
#       6
#       comment: foxtrot
Attempt to free unreferenced scalar: SV 0x28c6628 during global destruction.
./dbd-csv.t ... ok
./text-csv.t .. 1/? # Records
# a: alpha, b: beta has 3 observations
#       9 8 7
#       comment: soup
# a: alpha, b: bravo has 1 observations
#       6
#       comment: foxtrot
./text-csv.t .. ok
All tests successful.
Files=2, Tests=6,  1 wallclock secs ( 0.02 usr  0.00 sys +  0.18 cusr  0.04 csys =  0.24 CPU)
Result: PASS

See Also

requires 'DBD::CSV', '== 0.49';
requires 'Text::CSV_XS', '== 1.26';
requires 'Test::More', '== 1.302075';
requires 'Mojo::Base';
## -*- perl -*-
use strict;
use warnings;
use DBI;
use Test::More;
use lib '.';
use Record;
use VariableColumns qw{after_parse_combine_cols};
my $options = {
csv_eol => "\n",
csv_sep_char => " ",
csv_quote_char => '"',
csv_escape_char => '\\',
csv_callbacks => {
after_parse => \&after_parse_combine_cols
}
};
my @cols = qw{a b how_many observations comment};
my $dbh = DBI->connect('dbi:CSV:', undef, undef,
{
f_schema => undef,
f_dir => '.',
f_dir_search => [],
f_ext => '.csv',
f_lock => 2,
f_encoding => "utf8",
%$options,
csv_tables => {
input => { f_file => 'input.csv' }
},
RaiseError => 1,
PrintError => 1,
FetchHashKeyName => "NAME_lc",
}) or die $DBI::errstr;
ok($dbh, 'connect');
$dbh->{csv_tables}{input} = { col_names => \@cols };
my $sth = $dbh->prepare('select * from input');
$sth->execute;
my @rows;
while (my $row = $sth->fetchrow_hashref) {
is(keys(%$row), @cols, 'correct column count');
push @rows, Record->new(%$row);
}
$sth->finish;
diag 'Records';
diag $_->to_string for @rows;
done_testing();
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
"alpha" "beta" 3 9 8 7 "soup"
"alpha" "bravo" 1 6 "foxtrot"
package Record;
use Mojo::Base -base;
has [qw{a b how_many observations comment}];
sub to_string {
my $self = shift;
my $str = "a: $self->{a}, b: $self->{b} has $self->{how_many} observations\n";
$str .= "\t". join(' ', split(/\^/, $self->observations)) . "\n";
$str .= "\tcomment: $self->{comment}\n";
return $str;
}
1;
## -*- perl -*-
use strict;
use warnings;
use Test::More;
use Text::CSV_XS;
use lib '.';
use Record;
use VariableColumns qw{after_parse_combine_cols};
my $options = {
eol => "\n",
sep_char => " ",
quote_char => '"',
escape_char => '\\',
callbacks => {
after_parse => \&after_parse_combine_cols
}
};
my @cols = qw{a b how_many observations comment};
my $text_csv = new_ok 'Text::CSV_XS', [ $options ];
$text_csv->column_names(@cols);
open my $fh, "<:encoding(utf8)", "input.csv" or die "input.csv: $!";
my @rows;
while (my $row = $text_csv->getline_hr ($fh)) {
is(keys(%$row), @cols, 'correct column count');
push @rows, Record->new(%$row);
}
close $fh;
diag 'Records';
diag $_->to_string for @rows;
done_testing();
package VariableColumns;
use strict;
use warnings;
use base qw{Exporter};
our @EXPORT_OK = qw{after_parse_combine_cols};
sub combine_cols {
my ($data, $index, $combine_char) = @_;
$combine_char ||= '^';
my $combine_cols = $data->[$index];
my $next_col = $index + 1;
splice(@$data, $next_col, $combine_cols,
join($combine_char, @$data[$next_col .. ($index + $combine_cols)]));
}
sub after_parse_combine_cols {
my ($csv, $data) = @_;
combine_cols($data, 2);
return;
}
1;
@ronsavage
Copy link

ronsavage commented Jan 16, 2017

ron@zigzag:~/t$ prove .
./dbd-csv.t ... 1/? # CSV_XS ERROR: 1000 - INI - Unknown attribute 'quote_empty' @ rec 0 pos 0
# CSV_XS ERROR: 1000 - INI - Unknown attribute 'quote_empty' @ rec 0 pos 0
# CSV_XS ERROR: 1000 - INI - Unknown attribute 'quote_empty' @ rec 0 pos 0
# CSV_XS ERROR: 1000 - INI - Unknown attribute 'quote_empty' @ rec 0 pos 0
DBD::CSV::st execute failed: Fetch from undefined handle [for Statement "select * from input"] at ./dbd-csv.t line 52.
DBD::CSV::st execute failed: Fetch from undefined handle [for Statement "select * from input"] at ./dbd-csv.t line 52.
# Tests were run but no plan was declared and done_testing() was not seen.
# Looks like your test exited with 25 just after 1.
./dbd-csv.t ... Dubious, test returned 25 (wstat 6400, 0x1900)
All 1 subtests passed 
./text-csv.t .. 1/? 
#   Failed test 'undef isa 'Text::CSV_XS''
#   at ./text-csv.t line 26.
#     undef isn't defined
Can't call method "column_names" on an undefined value at ./text-csv.t line 28.
# Tests were run but no plan was declared and done_testing() was not seen.
# Looks like your test exited with 255 just after 1.
./text-csv.t .. Dubious, test returned 255 (wstat 65280, 0xff00)
Failed 1/1 subtests 

Test Summary Report
-------------------
./dbd-csv.t (Wstat: 6400 Tests: 1 Failed: 0)
  Non-zero exit status: 25
  Parse errors: No plan found in TAP output
./text-csv.t (Wstat: 65280 Tests: 1 Failed: 1)
  Failed test:  1
  Non-zero exit status: 255
  Parse errors: No plan found in TAP output
Files=2, Tests=2,  1 wallclock secs ( 0.02 usr  0.01 sys +  0.18 cusr  0.01 csys =  0.22 CPU)
Result: FAIL
ron@zigzag:~/t$ perl -v

This is perl 5, version 20, subversion 2 (v5.20.2) built for x86_64-linux

@ronsavage
Copy link

ronsavage commented Jan 17, 2017

ron@zigzag:~/t$ prove .
./dbd-csv.t ... 1/? # Records
# a: alpha, b: beta has 3 observations
#       9 8 7
#       comment: soup
# a: alpha, b: bravo has 1 observations
#       6
#       comment: foxtrot
Attempt to free unreferenced scalar: SV 0x182c9b0 during global destruction.
./dbd-csv.t ... ok   
./text-csv.t .. 1/? # Records
# a: alpha, b: beta has 3 observations
#       9 8 7
#       comment: soup
# a: alpha, b: bravo has 1 observations
#       6
#       comment: foxtrot
./text-csv.t .. ok   
All tests successful.
Files=2, Tests=6,  0 wallclock secs ( 0.03 usr  0.00 sys +  0.18 cusr  0.01 csys =  0.22 CPU)
Result: PASS

@ronsavage
Copy link

ronsavage commented Jan 17, 2017

Hi Roy

I deliberately use an old version of Test::More to minimize the pre-reqs of my modules [*] since I get complaints if I test using the latest available versions! Of course not all my modules were tested with an old Test::More, just recent ones.

[*] https://metacpan.org/author/RSAVAGE

shell> cpanm DBI
DBI is up to date. (1.636)
shell> pmversion Test::More
1.001002
shell> pmversion Mojo::Base
Module Mojo::Base does not define $VERSION
shell> pmversion Mojolicious
7.19
shell> pmversion Text::CSV_XS
1.15

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment