All posts by Marc Durdin

RIGHTeously tripping over T-SQL’s LEN function

We tripped over recently on our understanding of Microsoft SQL Server’s T-SQL LEN function.  The following conversation encapsulates in a nutshell what any sensible developer would assume about the function.

@marcdurdin I guess the answer is, removing the line would give the same result. Right? 🙂

— S Krupa Shankar (@tamil) April 23, 2013

Now, I wouldn’t be writing this blog post if that was the whole story.  Because, like so many of these things, it’s not quite that simple.

Originally, we were using RIGHT(string, LEN(string) – 2) to trim two characters off the front of our string.  Or something like that.  Perfectly legitimate and reasonable, one would think.  But we were getting strange results, trimming more characters than we expected.

It turns out that T-SQL’s LEN function does not return the length of the string.  It returns the length of the string, excluding trailing blanks.  That is, excluding U+0020, 0x20, 32, ‘ ‘, or whatever you want to call it.  But not tabs, new lines, zero width spaces, breaking or otherwise, or any other Unicode space category characters.  Just that one character.  This no doubt comes from the history of the CHAR(n) type, where fields were always padded out to n characters with spaces.  But today, this is not a helpful feature.

Of course, RIGHT(string) does not ignore trailing blanks

But here’s where it gets really fun.  Because a post about strings is never complete until you’ve done it in Unicode.  Some pundits suggest using DATALENGTH to get the actual length of the string.  This returns the length in bytes, not characters (remember that NCHAR is UTF-16, so 2 bytes per character… sorta!).  Starting with SQL Server 2012, UTF-16 supplementary pairs can be treated as a single character, with the _SC collations, so you can’t even use DATALENGTH*2 to get the real length of the string!

OK.  So how do you get the length of a string, blanks included, now that we’ve established that we can’t use DATALENGTH?  Here’s one simple way:

  SET @realLength = LEN(@str + ‘.’) – 1

Just to really do your head in, let’s see what happens when you use LEN with a bunch of garden variety SQL strings.  I should warn you that this is a display artefact involving the decidedly unrecommended use of NUL characters, and no more, but the weird side effects are too fun to ignore.

First, here’s a set of SQL queries for our default collation (Latin1_General_CI_AS):

Note the output.  Not exactly intuitive!  Now we run the Unicode version:

Not quite as many gotchas in that one?  Or are there?  Notice how the first line shows a wide space for the three NUL characters — but not quite as wide as the Ideographic space…

Now here’s where things go really weird.  Running in Microsoft’s SQL Server Management Studio, I switch back to the first window, and, I must emphasise, without running any queries, or making any changes to settings, take a look at how the Messages tab appears now!

That’s right, the first line in the messages has magically changed!  The only thing I can surmise is that switching one window into Unicode output has affected the whole program’s treatment of NUL characters.  Let that be a warning to you (and I haven’t even mentioned consuming said NULs in C programs).

Hell of the South

Held each year just before the Hell of the North, Paris-Roubaix, this race nonetheless bears little resemblance to that famous race. It’s a 60km race over lumpy terrain just south of Hobart, Tasmania, and has no cobbles.
 
I had not planned to do this race. I had looked wistfully at the weather forecast and then my wife surprised me by encouraging me to go. Bear in mind that we have a one month old little boy, and so sleep, fitness and all the usual things necessary for riding competitively were somewhat out the door, and so it was a big gift from my wife for me to go and ride.
Still, I did jump at the chance to ride. My last race had been about a year ago, and I had really enjoyed it. I figured I’d struggle today but decided to go along, give it a crack, and just make the most of the opportunity.
The weather was grand: warm, a light breeze, and overcast meant dry roads and a pleasurable ride whatever happened. It also meant there would be a decent turnout, and we had nearly 20 starters in B Grade. I chose to ride B Grade, mostly because my mates would never let me live it down if I sandbagged in a lower grade!
The B Grade bunch – I’m on the far left, yep in the Strava gear – photo courtesy of Clive Roper
Being a scratch race, A were off first, followed by the lower grades, one after another. B set off in a somewhat haphazard manner, at a pace that was more reminiscent of an afternoon amble to the pub than a race. Not that I was complaining…
C grade proved just how somnolent that pace really was when they roared past us and made the whole grade feel deeply ashamed of their lacklustre efforts thus far. B grade subsequently made up for this by surging back past C.
However C Grade were not done yet. They came back past B Grade and their efforts were probably solely responsible for a respectable pace in the bunch up the first real climb.  Barry rode off the front a little up the climb, but we all knew he wasn’t silly enough to try and solo the entire race, so no one panicked.
At this point, my legs were a little heavy but I was doing fine. Dogga and I had been a little silly on Thursday with a well-over-threshold attack up the lower slopes of Strickland Ave, and while I suffered somewhat from this, I think he suffered more!
The next 40 or so kilometres proved to be all over the show. A dog’s breakfast. A shambles.  A few half-hearted attempts to setup a pace line were tried, and some even more half-hearted attacks followed, but mostly it was just surge followed by soft pedal!
Just outside Kettering.  Photo courtesy Clive Roper

This meant the final climb would be intense. Everyone was saving their bikkies for the Nicholl’s Rivulet climb.  Everyone except for me. I was just hanging on, using tactics like drifting from the front to the back of the bunch on the little climbs, and feeling very aware that my longest rides recently had been only 30km or so!

Once through Kettering, the pace started to hot up a bit. A 1.2km climb at 6% sorted out the candidates from the pretenders. Me, a pretender for sure as I watched the bunch get 5 seconds — doesn’t seem like much, but was enough to make it very hard indeed to get back on. Through the turn onto the Nichol’s Rivulet climb, just a few seconds off the back and I could feel my legs telling me “enough”. I struggled to rejoin the bunch but never really made it back.
I plodded up the final climb, with a few other riders ahead and just out of reach.  Over the top and decided that I would give it all I had on the descent and flat run into the line — not that I’d catch the leaders, but at least I could be somewhat satisfied with the day’s efforts!
I managed to catch Sam, but Brendon and one other rider remained tantalisingly out of reach.  Adam (congratulations, I understand, are in order), Joe, Mark, Barry, Jonathon, James, Mike and others were even further up the road!
At the finish, with a very empty road behind me…  Photo courtesy Dan Wood
After this appalling debacle, I expect the Strava team will want their Ambassador Kit back 😉  It seems that the great Velo Flow website is currently down, so we can’t relive the race in all its glory at present, but hopefully it will be back soon!  Update: Velo Flow is back!  Replay the race.  You can easily spot Gerald (overall A Grade winner), and the mysterious flying Torben, and Dogga.  I am represented by the bigger blue dot…

The Fragile Abstract Factory Delphi Pattern

When refactoring a large monolithic executable written in Delphi into several executables, we ran into an unanticipated issue with what I am calling the fragile abstract factory (anti) pattern, although the name is possibly not a perfect fit.  To get started, have a look at the following small program that illustrates the issue.

program FragileFactory;

uses
  MyClass in 'MyClass.pas',
  GreenClass in 'GreenClass.pas',
  //RedClass in 'RedClass.pas',
  SomeProgram in 'SomeProgram.pas';

var
  C: TMyClass;
begin
  C := TMyClass.GetObject('TGreenClass');
  writeln(C.ToString);
  C.Free;

  C := TMyClass.GetObject('TRedClass');  // oh dear… that’s going to fail
  writeln(C.ToString);
  C.Free;
end.
unit MyClass;

interface

type
  TMyClass = class
  protected
    class procedure Register;
  public
    class function GetObject(ClassName: string): TMyClass;
  end;

implementation

uses
  System.Contnrs,
  System.SysUtils;

var
  FMyClasses: TClassList = nil;

{ TMyObjectBase }

class procedure TMyClass.Register;
begin
  if not Assigned(FMyClasses) then
    FMyClasses := TClassList.Create;
  FMyClasses.Add(Self);
end;

class function TMyClass.GetObject(ClassName: string): TMyClass;
var
  i: Integer;
begin
  for i := 0 to FMyClasses.Count – 1 do
    if FMyClasses[i].ClassNameIs(ClassName) then
    begin
      Result := FMyClasses[i].Create;
      Exit;
    end;

  Result := nil;
end;

initialization
finalization
  FreeAndNil(FMyClasses);
end.
unit GreenClass;

interface

uses
  MyClass;

type
  TGreenClass = class(TMyClass)
  public
    function ToString: string; override;
  end;

implementation

{ TGreenClass }

function TGreenClass.ToString: string;
begin
  Result := 'I am Green';
end;

initialization
  TGreenClass.Register;
end.

What happens when we run this?

C:\src\fragilefactory>Win32\Debug\FragileFactory.exe
I am Green
Exception EAccessViolation in module FragileFactory.exe at 000495A4.
Access violation at address 004495A4 in module ‘FragileFactory.exe’. Read of address 00000000.

Note the missing TRedClass in the source.  We don’t discover until runtime that this class is missing.  In a project of this scale, it is pretty obvious that we haven’t linked in the relevant unit, but once you get a large project (think hundreds or even thousands of units), it simply isn’t possible to manually validate that the classes you need are going to be there.

There are two problems with this fragile factory design pattern:

  1. Delphi use clauses are fragile (uh, hence the name of the pattern).  The development environment frequently updates them, typically they are not organised, sorted, or even formatted neatly.  This makes validating changes to them difficult and error-prone.  Merging changes in version control systems is a frequent cause of errors.
  2. When starting a new Delphi project that utilises your class libraries, ensuring you use all the required units is a hard problem to solve.

Typically this pattern will be used with in a couple of ways, somewhat less naively than the example above:

  1. There will be an external source for the identifiers.  In the project in question, these class names were retrieved from a database, or from linked resources.
  2. The registered classes will be iterated over and each called in turn to perform some function.

Of course, this is not a problem restricted to Delphi or even this pattern.  Within Delphi, any unit that does work in its initialization section is prone to this problem.  More broadly, any dynamically linking registry, such as COM, will have similar problems.  The big gotcha with Delphi is that the problem can only be resolved by rebuilding the project, which necessitates rollout of an updated executable — much harder than just re-registering a COM object on a client site for example.

How then do we solve this problem?  Well, I have not identified a simple, good clean fix.  If you have one, please tell me!  But here are a few things that can help.

  1. Where possible, use a reference to the class itself, such as by calling the class’s ClassName function, to enforce linking the identified class in.  For example:
    C := TMyClass.GetObject(TGreenClass.ClassName);
    C := TMyClass.GetObject(TRedClass.ClassName);
  2. When the identifiers are pulled from an external resource, such as a database, you have no static reference to the class.  In this case, consider building a registry of units, automatically generated during your build if possible.  For example, we automatically generate a registry during build that looks like this:
    unit MyClassRegistry;
    
    // Do not modify; automatically generated 
    
    initialization
    procedure AssertMyClassRegistry;
    
    implementation
    
    uses
      GreenClass,
      RedClass;
    
    procedure AssertMyClassRegistry;
    begin
      Assert(TGreenClass.InheritsFrom(TMyClass));
      Assert(TRedClass.InheritsFrom(TMyClass));
    end; 
    
    end.

    These are not assertions that are likely to fail but they do serve to ensure that the classes are linked in.  The AssertMyClassRegistry function is called in the constructor of our main form, which is safer than relying on a use clause to link it in.

  3. Units that can cause this problem can be identified by searching for units with initialization sections in your project (don’t forget units that also use the old style begin instead of initialization — a helpful grep regular expression for finding these units is (?s)begin(?:.(?!end;))+\bend\.).  This at least gives you a starting point for making sure you test every possible case.  Static analysis tools are very helpful here.
  4. Even though it goes against every encapsulation design principle I’ve ever learned, referencing the subclass units in the base class unit is perhaps a sensible solution with a minimal cost.  We’ve used this approach in a number of places.
  5. Format your use clauses, even sorting them if possible, with a single unit reference on each line.  This is a massive boon for source control.  We went as far as building a tool to clean our use clauses, and found that this helped greatly.

In summary, then, the fragile abstract factory (anti) pattern is just something to be aware of when working on large Delphi projects, mainly because it is hard to test for: the absence of a unit only comes to light when you actually call upon that unit, and due to the fragility of Delphi’s use clauses, unrelated changes are likely to trigger the issue.

Cursing over cursor keys

A follow-up post, 29 Sep 2014: Cursor Keys Have Not Improved.

As you may know, I do a fair bit of work with keyboards.  This means I have collected quite a number of hardware keyboards over the last few years.  I do a lot of testing with various keyboards and use a number of computers with different hardware keyboards for both testing and development purposes.

One of the more irritating issues I experience moving between these keyboards is in the way manufacturers keep rearranging the cursor key block.  As a touch typist, I am continually pressing the wrong cursor key, or Delete instead of Home, and so on.  And that’s just the desktop keyboards.  When it comes to notebooks I have lost all hope.

The ISO/IEC 9995-5 standard does require keyboard manufacturers to keep those cursor keys in one of two shapes:

That’s it.  Not very prescriptive.  One almost wonders why they bothered!  So let’s have a look at the problem with the keyboards in my office.  Starting with desktop keyboards, I found 12 keyboards on and around my desk (and one in a second office), with no less than 6 different arrangements of this cursed cursor zone. I have included 8 of the keyboards in the image below:

Eight keyboards.  Can you spot the ones with identical cursor layouts?

I drew up the six different layouts I found, grouping the keys by colour (sorry if you are colour blind).  The top two layouts seem to be where most keyboards are going today.  The middle two are more traditional, and the final two layouts were invented, I am convinced, purely to cause me grief.

I aligned the layout diagrams with the right hand side of the main alphanumeric keyboard block: this reflects where my hands sit normally.  I hardly need to explain the difficulties with the constant rearrangement of the Home, End, PgUp, PgDn, Ins and Del keys, but I will note that the inconsistency of the cursor block position is almost as much of a problem: I get used to the position of the down arrow key on one keyboard, switch to another keyboard and find myself hitting left arrow instead from muscle memory.

Notebook manufacturers have somewhat more of an excuse: they are trying to fit a bunch of keys into a much smaller space.  Even so, the variety is pretty amazing.  I didn’t even include the couple of dead laptops that have not yet made their way into the rubbish.  Apple and Acer take top marks for consistency.  Toshiba, not so much…  I threw in a Microsoft Surface RT tablet keyboard for good measure!  Some of the keyboards use the Fn key to access PgUp, PgDn, Home or End (or even Del).  These are of course very inconsistently mapped, if you can even find them…

Surface RT, MacBook, Acer netbook, Acer ultrabook,
Toshiba notebook, MacBook, Toshiba notebook

Even soft keyboards suffer.  The following 5 images are all from the same company, Microsoft.  Of note is that the position of the Fn key changes between Windows 7 and Windows 8. In 3 of the images, the position of the up arrow key is just slightly misaligned with the down arrow; this may not be a problem in use but it is visually irritating!

Windows 8 Accessibility, Windows 7 Accessibility,
Windows XP, Win 8 Touch Optimised, Win 8 Touch Full.

 

How not to re-raise an exception in Delphi

Just a quick exception management tip for today.

I was debugging a weird cascade of exceptions in an application today — it started with an EOleException from a database connection issue, and rapidly degenerated into a series of EAccessViolation and EInvalidPointer exceptions: often a good sign of Use-After-Free or Double-Free scenarios.  Problem was, I could not see any place where we could be using a object after freeing it, even in the error case.

Here’s a shortened version of the code:

procedure ConnectToDatabase;
begin
  try
    CauseADatabaseException;  // yeah... bear with me here.
  except
    on E: EDatabaseError do
    begin
      E.Message := 'Failed to connect to database; the '+ 
                   'error message was: ' + E.Message;
      raise(E);
    end;
  end;
end;

Can you spot the bug?

I must admit I read through the code quite a few times before I spotted it.  It’s not an in-your-face-look-at-me type of bug!  In fact, the line in question appears to be completely logical and plausible.

Okay, enough waffle.  The bug is in the last line of the exception handler:

      raise(E);

When we call raise(E) we are telling Delphi that here is a shiny brand new exception object that we want to raise.  After Delphi raises the exception object, the original exception object is freed, and … wait a minute, that’s the exception object we were raising!  One delicious serve of Use-After-Free or Double-Free coming right up!

We should be doing this instead:

      raise;  // don't reference E here!

Another thing to take away from this is: remember that you don’t control the lifetime of the exception object.  Don’t store references to it and expect it to survive.  If you want to maintain knowledge of an inner exception object, use Delphi’s own nested exception management, available since Delphi 2009.

When driving in a strange place doesn’t turn out quite the way you were expecting

So I flew in from Hobart, with certain expectations and negative assumptions about what driving here in Seattle would be like.  My expectations about driving here in Washington State have certainly been confounded. While I have driven here once before, it was only for a day and I was pretty jet-lagged. Here are some of my observations:

  1. Drivers are courteous; super ridiculously amazingly courteous. If, as a pedestrian, I step out onto the street, all the traffic stops for me. And not screeching to a stop and foaming at the mouth out the window, like you might expect in Australia, but just gently waiting for me to make my own foolish way across the road. Whoa.
  2. If I look like I want to cross the road, all the traffic stops for me. Yes, that’s right. And so of course I get confused by this because in Australia the complete opposite behaviour is the norm.
  3. When I ride a bike, cars approaching from behind slow down, make sure it is safe, and when the road is clear, pass me with a gentle acceleration and plenty of space. Freaky. So different to the Hobart approach of flying past mere inches from you.
  4. But stop signs completely suck. Especially four way stops. Priority is by order of arrival to the intersection. So confusing. And they are everywhere! I reckon the entire US economy could be resurrected just from the fuel savings in replacing these stop signs with roundabouts, let alone via the increase in productivity because of the savings in travel time.
  5. Right turn on red light. So you stop at the light, and if the road is clear, you can turn right even when the light is red (Aussie drivers, remember that Americans drive on the wrong side of the road). The only time you are not allowed to do this is when a sign informs you that there is “No turn on red”. But this typically only happens at intersections where visibility is lacking. Oh yeah, they hang their traffic lights up here, like Christmas decorations (but I did already know that…)

  1. But what about this traffic light?  What do you do here?  This is a trick question for Australian drivers.

    Wrong answer! It turns out that you are allowed to do a right turn on the red arrow. Yep, even though that red arrow seems to be specifically telling you otherwise. I can quote from the Washington Department of Transportation bylaws if you don’t believe me.

Of course there will be exceptions to some of the above – I did see one aggressive driver here. But only one.  And I have no idea about the situation anywhere except the Bellevue/Redmond area. But expectations about driving here completely shattered, in a good way!

The Southern Ocean… According to Apple

Just like everyone else, I found Apple’s new train wreck release of iOS 6 maps bizarre. It’s rather unlike Apple to publish such an unpolished feature. The straight-line vector graphics look amateur when zoomed in and generally a step back from the Google maps. But worse than the lack of polish is of course the outright data errors. I can understand a misplaced town in an insignificant country such as the United Kingdom. But to misplace a whole ocean? I mean, it’s not like there’s that many of them to keep track of.

Here’s the evidence. You’ll also note the comparatively minor issue of a missing river. Minor compared to an ocean, anyway (on Google Maps):




However, before you hanker for the good old Google Maps, let’s take a quick look at the same location:

Looks good, river staying right where it belongs like a good little river, and the Southern Ocean has decided to skip town.  But there’s something different about that Derwent Park Rd: it seems to be a major through-road on Google Maps but is a dead end on Apple’s map:

Google should know it’s not a major through road.  Their Street View car even found the evidence. It’s a private road.  With a gate.

What’s the moral of the story?  Use Bing Maps?  Nope.  They include our little dried-up ocean, fortunately nameless, but also perpetuate that little issue with the closed road (and yes, both Bing and Google will happily direct you to crash through the gate, if you ask them for directions).

Still, I think Apple’s maps take home the prize!

How we told our girls about the new baby

A couple of months ago, we announced to our 5 and 8 year old daughters that Joey was pregnant.  I decided to make the announcement a little more interesting for them, and here’s what we did.  After a little initial preparation, I called the girls into the lounge room, and handed them an envelope.  I told them that they had to solve the riddle in the envelope and that would tell them where to look for the next clue.

Great excitement!  What an awesome game they both thought!

Without any further ado, the first riddle.


Gosh, that was a hard one to start with.  We suggested they dissect the riddle, and figure out what else a ripple could be called.  Bethany suggested a wave?  A tiny tiny wave?  A microwave?  The girls rushed to the microwave, and sure enough, inside it, was an envelope, with two sheets of paper. We instructed the girls to put the first sheet aside, and figure out the next riddle:

This one was easier, and Hannah (our younger), clicked to it: the toilet duck! And there, near the toilet, was an envelope!

By this stage, both the girls were getting the hang of it and both making lots of suggestions, and it didn’t take either of them long to figure out that perhaps they should look in the car for the next clue!

And with this one, the only stumbling block they ran into, was which sleeping loft?  They decided it couldn’t be theirs, because they had been playing in their room and hadn’t seen me coming in!  And the final envelope was in our loft.

They rushed back down with the final envelope to the lounge room where we were waiting, and put the four other pieces of paper together in order:

Their immediate response was, “But Mummy’s not having a baby!”  “I don’t believe it!”  “You are just joking!” It took us several minutes to convince them that it was actually true!

That afternoon, we told our parents the news, and the girls wrote their own riddle clues (which have unfortunately since gone missing) and did their own message for their grandparents!

Delphi, Win32 and leaky exceptions

Have you ever written any Delphi code like the following snippet?  That is, have you ever raised a Delphi exception in a Win32 callback?  Or even just failed to handle potential exceptions in a callback?

    function MyWndEnumFunc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
    begin
      if hwnd = TForm4(lParam).Handle then
        raise Exception.Create('Raise an exception just to demonstrate the issue');
      Result := True;
    end;

    procedure TForm4.FormCreate(Sender: TObject);
    begin
      try
        EnumWindows(@MyWndEnumFunc, NativeInt(Self));
      except
        on E:Exception do
          ShowMessage('Well, we unwound that exception.  But does Win32 agree?');
      end;
    end;

Raymond Chen has posted a great blog today about why that approach will eventually end in tears.  You may get away with it for a while, or you may end up with horrific stack or heap corruption. The moral of the story is, any time you have a Win32 callback function, you need to make sure no exceptions leak.  Like this:

function MyWndEnumFunc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
begin
  try
    if hwnd = TForm4(lParam).Handle then
      raise Exception.Create('Raise an exception just to demonstrate the issue');
    Result := True;
  except
    // Handle the exception, perhaps pass it to Application.HandleException,
    // or log it, or abort your app.  Just don’t let it bubble through any
    // Win32 code.  You need to write the HandleAllExceptions function!
    HandleAllExceptions;
    Result := False;
  end;
end;

If you use Delphi’s AllocateHwnd procedure, remember that it also does not handle exceptions for you (I’ve just reported this in QualityCentral as QC108653 as this caveat should at least be documented).  So you need to do it:

procedure TForm4.MyAllocatedWindowProc(var Message: TMessage);
begin
  try
    if Message.Msg = WM_USER then
      raise Exception.Create('Go wild!');
  except
    Application.HandleException(Self);  // Or whatever, just don’t let it leak
  end;
  with Message do Result := DefWindowProc(FMyHandle, Msg, wParam, lParam);
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  FMyHandle := AllocateHwnd(MyAllocatedWindowProc);
  SendMessage(FMyHandle, WM_USER, 0, 0);
end;