Changeset 344 for trunk


Ignore:
Timestamp:
06/11/12 18:05:15 (13 years ago)
Author:
Kris Deugau
Message:

/trunk

Work around bizarre SQL un-bug where:

SELECT <stuff> UNION (SELECT <stuff> ORDER BY ...)

not only didn't essentially glue the results of the two SELECTs together
serially (mildly confusing but a nonissue), but the ORDER BY was not obeyed
properly and resulted in records returned in the wrong relative order
overall (a problem when further processing required that relative ordering
of the records from the second SELECT).

This caused PTR template entries in reverse zones to not stack/overlay/cascade
properly on export, because larger netblocks returned first (against the ORDER
BY) prevented the smaller, more specific blocks from being expanded.

See #26

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r343 r344  
    41934193  my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status FROM revzones WHERE status=1 ".
    41944194        "ORDER BY masklen(revnet) DESC");
     4195# For reasons unknown, we can't sanely UNION these statements.  Feh.
     4196# Supposedly it should work though (note last 3 lines):
     4197## PG manual
     4198#UNION Clause
     4199#
     4200#The UNION clause has this general form:
     4201#
     4202#    select_statement UNION [ ALL ] select_statement
     4203#
     4204#select_statement is any SELECT statement without an ORDER BY, LIMIT, FOR UPDATE, or FOR SHARE clause. (ORDER BY
     4205#and LIMIT can be attached to a subexpression if it is enclosed in parentheses. Without parentheses, these
     4206#clauses will be taken to apply to the result of the UNION, not to its right-hand input expression.)
     4207
     4208  my $soasth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id ".
     4209        "FROM records WHERE rdns_id=? AND type=6");
    41954210  $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id ".
    4196         "FROM records WHERE rdns_id=? AND type=6 UNION ".
    4197         "(SELECT host,type,val,distance,weight,port,ttl,record_id ".
    41984211        "FROM records WHERE rdns_id=? AND not type=6 ".
    4199         "ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet))");
     4212        "ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet)");
    42004213  $revsth->execute();
    42014214  while (my ($revid,$revzone,$revstat) = $revsth->fetchrow_array) {
    4202     $recsth->execute($revid, $revid);
     4215    $soasth->execute($revid);
     4216    my (@zsoa) = $soasth->fetchrow_array();
     4217    _printrec_tiny($datafile,'y',\%recflags,$revzone,
     4218        $zsoa[0],$zsoa[1],$zsoa[2],$zsoa[3],$zsoa[4],$zsoa[5],$zsoa[6],'','');
     4219
     4220    $recsth->execute($revid);
    42034221    while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid) = $recsth->fetchrow_array) {
    42044222      next if $recflags{$recid};
Note: See TracChangeset for help on using the changeset viewer.