I am running 64 bit active perl v5.22.1 on a windows 10 dual AMD box. I am writing a generic database load routine that reads a CSV per table and generates and executes SQL into Postgres. The CSV's have table declarations first followed by a token __COLUMNS__ followed by the data to insert in the table. One of the table declarations I configure takes the form: "FK", local column, foreign table name, foreign PK. So I have to sort the CSVs so that wherever such a declaration exists, the foreign table is created before the table in which the FK declaration is made. For simplicity, I load all the CSVs first into a hash of array of array, table name is hash key with value being the CSV data for that table. Some issues and points of interest arise from this.

1) Given the basics of the sorting (structure is in $cvsQ):

$obj->_getset('csvQ', $csvQ); for my $csvq ( sort _DBsort4create keys %$csvQ ) { $obj->_getset('ar', $csvq); $obj->_arr2db; # create and populate table }
...the table names appear in pairs $a and $b and the sort routine needs access to $obj to compare the CSV data for the two tables. When I tried passing parameters to the sort routine or putting $obj-> in front of the sort routine call, I got a syntax error. But when I removed the $obj-> from the call, this corrected the syntax error. But strangely, the code below which shifts the first parameter magically DWIMmed by getting the right object...
sub _DBsort4create { my $obj = shift; my $csvref = $obj->_getset('csvQ'); die Dumper( $csvref->{$a} ); # next steps: 1) check for comparison already done # 2) if so just return old result # 3) get FK declaration, store implied # comparison unless contradicts history # if contradiction, give message that database design cannot be physically implemented }
the above code therefore displayed a dump of the AoA for the first key about to be sorted in the HoAoA. So how did it acquire $obj as a parameter given that the sort routine is called bare? There is a CPAN module that provides a sort routine for objects but that isn't the same thing at all. I could pass the structure via a package variable but then I haved two evils to choose from: global variables versus undocumented features.

2) If $a does not reference $b or vice versa, I can return 0 otherwise I can optimise by retrieving a previous comparison of the same pair before delving into the structure if already compared. But the problem is that there could be circular references that cannot be pairwise detected which one would expect to cause sort to go into an infinite loop. So the second issue is: given the list of established pairwise comparisons, how to test for an implied contradiction with the current iteration of sort e.g. M > N and N > P but one of the current pair declares P > M and so would cause an infinite loop if the sort routine were allowed to continue. And of course this suggests I need to do something other than pairwise sort in the first place.

The best idea I have is to build the history of comparisons as a list of groups (hashes) of comparisons instead of a list of comparisons, so that elements not explicitly sorted are left unsorted in each hash and the criteria for predicting an infinite loop becomes an attempt to put the same table in more than one group. Or perhaps someone has a less esoteric way to perform the test?

Many thanks!

Simon

One world, one people


In reply to Sort mechanics problems with objects and potentially contradicting comparisons (would cause infinite loop) by anonymized user 468275

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.