Month: October 2003

Short Story, Null is not null, inheritance and other stuff

My new short story is The End of All Meeting. It’s a bit preachy but it helped me sort some thngs out. Have a read if you want.

Null is not Null

If you select length(’’) from dual in Oracle what you get in return is a null. I was trying to prevent string buffer overflow using some code like:

if length(buffer)+length(message) < 32767
then
 buffer := buffer || message ;
end if ;

Ah yes but buffer was initialised to ‘’, with me thinking that its length would be 0. Nope, its length is null. Then remember the golden rule any operation involving null returns a null, any boolean operation is always false. Yes, you guessed it, the buffer remained empty. This took a bit of finding because I thought I’d dealt with it by setting the buffer to ‘’. Interestingly this means that you can’t have a varchar2 string that has a length of 0, you have to nvl the length to 0. Of course, if they fixed this a mountain of code would break, I have used it myself occasionally.

This gives us the interesting paradox

null is false

not null is false

null <> not null is false

My head hurts.

Fun with inheritance

I got to the bottom of the bug with my old code. I had refactored a class that I was doing a lot of inheriting from into an abstract class so we had something like:

public abstract class XMLActions
extends org.xml.sax.helpers.DefaultHandler
{
 String currentTable = “” ;
 static String sourceFile = “public_html\data-model.xml” ;
 boolean firstColumn = false ;
 boolean firstViewColumn = false ;
 boolean firstTable = false ;
 boolean doWhere = false ;
 PrintStream os = System.out ;
 Map tagTables = new HashMap() ;
 /* … */
 final public void characters
  ( final char[] ch
  , final int start
  , final int len )
 {
  if ( doWhere ) // we are inside a view
  {
   final String text = new String( ch, start, len ).trim();
   if( text.length() > 0 ) os.println(text);
  }
 }
}

The inheriting class (which was the original) implements an abstract method called handleViewWhereClause (trips off the tongue) that sets the doWhere boolean so that the text will be echoed out to the output stream. But silly me, I had left the instance variables in it when I factored it out. This class was setting its local attribute of the same name and the parent class was blithely ignoring it. Here endeth the lesson.

Making laptop screen fonts clearer in XP

Right click on the desktop. Select appearance, check effects, check cleartype on font smoothing. Got it from an O’Rielly book XP Pro : The missing manual. I might even buy it rather than looking at it in PC World, but probably not from them. I haven’t paid the retail price for a computer book in ages and I’m not about to start now. There’s also one on setting up WiFi which looked OK, but I haven’t had a problem with WiFi: just read the manual.

Blessings and good health all.

Keys sorted

Got me keys sorted. In the end I split the monsta query into two passes. Been having a hassle where some of the tables don’t have primary keys. I was trying to use primary keys as a first cut for the relationships in my deepcopy tables. Not a problem, will just have to be done by hand. As I’m prototyping now I decided to simply ignore the problem until it matters. Gone back to the high-level design and looking at the business rules.

Got postres going last night on the laptop. No problem.

Reviewed my project and discovered – horror! – a bug in one of the early phases that I need to think about. The generated SQL wouldn’t work in postgres ‘cos the view handler routine is knackered. Ah well; can’t be perfect all of the time.

Got a subscription copy of .Net developer. Now I just need to think of what I need to develop on it! Probably loads a tutorials to start with.

Watched DVD of Dog Soldiers – it was ok but if I see another pound of sausages covered with Kensington Gore (stage blood), I’ll have to hit someone. Then they superglued the sarge’s wound back together and he didn’t die. I dunno, I thought guts should twitch a bit, particularly when still attached, and he didn’t just die of some galloping infection before the werewolf magic took over and healed him.

Going to ring round the wifi network providers in Nottingham tonight with a view to taking the lappy and getting some connectivity. If you’re looking for Wifi stuff try http://www.wifinder.com/, I also had a go with http://www.wi-fizone.org/zoneLocator.asp but they didn’t seem to have as much info. Note for UK peeps, on the first site select United Kingdom, not UK, cos it wont’ find anything. Thanks to Roger for the URLs.

Discovered that the new google toolbar will selectively suppress popups. Very useful.

Envoi

ooh err missus, got me keys backwards

Hmmm … deepcopy utility was going back to parent’s primary key so we were getting duplicates on compound keys. Needed to redesign so that you know what your primary key is and the parent values are passed down. Sigh. It all seemed finished. Took me less than a day to get the receiving procedure written that takes the XML and generates the insert statements. Of course need to do the deep delete as well. Maybe just call the package deep? Forgot that getting a value doesn’t work with XML, you have to get the child node and get it’s value:

      currChild := xmldom.getFirstChild( currChild ) ;
      if xmldom.isNull( currChild )
      then
       retList( tagOrder ) := ’’;
      elsif xmldom.getNodeType(currChild) = xmldom.TEXT_NODE
      then
       retList( tagOrder ) := xmldom.getNodeValue( currChild ) ;
      end if ;

Note having to check for nullity – it doesn’t just give you a null back, oh no, that would mean it couldn’t throw a spurious exception and make you think it wasn’t working. Oracle site mentioned below very helpful, there is a FAQ section on the xmldom package.

Having fun with inline views to generate out the key references:

select  dct_child.table_id
,       dct_child.parent_table_id
,     (
        select distinct parent_cols.column_name
        from all_constraints parent
        ,  ALL_CONS_COLUMNS parent_cols
        ,    all_constraints child2
        ,    all_cons_columns child_cols2
        where  parent_cols.position = child_cols.position
        and     parent_cols.TABLE_NAME  = parent.table_name
        and     parent_cols.constraint_name = parent.constraint_name
        and     parent_cols.owner = parent.owner
        and     parent.table_name = dct_parent.table_name
        and     parent.constraint_type = ‘P’
        and     child2.r_owner = parent.owner
        and     child2.r_constraint_name = parent.constraint_name
        and     child_cols2.table_name = child2.table_name
        and     child_cols2.column_name = child_cols.column_name
        and     child_cols2.position = parent_cols.position
        and     child.table_name = child2.table_name
        )
,       child_cols.COLUMN_NAME
,       child_cols.position
,  child.constraint_name
from    ALL_CONS_COLUMNS child_cols
,      ALL_CONSTRAINTS child
,       deepcopy_tables dct_child
,       deepcopy_tables dct_parent
where   child.TABLE_NAME  = child_cols.table_name
and     child.constraint_name = child_cols.constraint_name
and     child.owner = child_cols.owner
and     child.table_name = dct_child.table_name
and     child.constraint_type = ‘P’
and     dct_parent.table_name = ‘CUSTOMER
and     dct_child.parent_table_id = dct_parent.table_id
;

Horrible isn’t it? If I’d joined directly I’d have had to outer join the parent key stuff (if it even would have worked).

Had a stomach bug yesterday. Not a lot of fun to be honest. Interesting drive to work today but fortunately it didn’t give me any gyp.

Having fun with new laptop (see savastore here – I upgraded to a 2.4 GHz processor and XP Pro). It has the ability to play CD’s without being switched on. Very handy. Will watch some DVDs tonight.

I found http://www.oracle-base.com/ a while ago and forgot to mention it. Seems to be better than technet for finding stuff.

Hogs and quiches compadres.

More about types in PL/SQL, Paddling etc.

Was trying to do something like:

type long_string is varchar2(32767) ;

The compiler didn’t like it at all. In fact you have to declare this :

subtype long_string is varchar2(32767) ;

It looks like the language designer was being a little pedantic to me but hey, what do I care, only had to RTFM. This does have the advantage in packages etc. that means you can now just say:

fred long_string ;

when you are declaring things, and if you want to change the size of things it’s easy and in one place. To go the whole hog you could have a package header with your standard types in (don’t need a body btw):

create or replace package project_types is
 subtype long_string is varchar2(32767) ;
 subtype short_string is varchar2(200) ;
 subtype flag is char(1) ;
 subtype delimiter is varchar2(10) ;
— And so on
end project types ;

Then just declare stuff as

fred project_types.long_string ;

Then you can insulate yourself against having to make global search/replace across your whole project. Subtypes transparently work within the base type. I would also recommend declaring yourself a ref cursor type (why there isn’t a standard one and you have to declare the king stupid thing every time is one of those little mysteries), if you haven’t got the SYS one available (sys.rc).

Paddling

Went to Holme Pierpoint and had a pretty good time except when I screwed up and came down the concrete, fell in and my roll wouldn’t work ‘cos I was being pressed back under by the force of the water. Need to work on rolling on both sides and using the reverse screw roll more. Next week’s practice items I think. Need to buy more thermals!

Laptop

My laptop has arrived so I can go on the road and work on my pet projects. My old lappy would just about run Mess Werd. Hey – I can even watch DVD’s! Short story about half done. Need to buy one of those security devices.

Looking forward to seeing the family this weekend.

Blogging works

Used my blog to locate some code I have used before. Very useful. Recommend blogging to everyone who needs to keep track of things. I had a look at my utilities package and it’s a bit out of date now

Blessings upon you all, dear readers (all 2 of you).

Tired, deep copy, PL/SQL tables whoop it up, baby

Been struggling the last few days with tiredness. Seem to keep waking up at 5 am, not a lot of fun to be honest. I’ve been wondering if it’s my IBS flaring up again. Suspect the tiredness comes from the weekend originally, where I paddled for 2 days and even had a drink in the evening. Probably paying for it now, methinks.

Deep copy

I’ve been working on a PL/SQL procedure to do a deep copy of an object from one schema to another. Sounds fairly trivial but the usual nonsense with security has screwed things up; you can’t select from all_tab_columns in a pl/sql procedure and look at someone else’s schema. I had to move to the main schema out of my own one, surprise! Currently creating an XML message (yet to work out mechanics of sending it). Alternate foreign keys to the same parent are a pain. There is a data structure here which allows you to browse across to other accounts the customer has, but only one has a direct relationship with the main account record. I need to work out how to make this go.

Having fun with oracle types (needed to create a complex structure that allows me to drill down rather than up). Look ma, multidimensional arrays:

declare
 type col_values is table of varchar2(2000) index by binary_integer ;
 type value_list is table of col_values index by binary_integer ;
 cv col_values ;
 vl value_list ;
begin
 cv(1) := ‘asdf’ ;
 vl(1) := cv ;
 dbms_output.put_line( vl(1)(1) ) ;
end ;

The syntax is fairly obvious in the end. I now have a complex type that holds the IDs of its children so it can go down to them recursively. Watch this space for a debugged version being posted some time soon.

I’m using a much underused trick with oracle tables. They are in fact sparse arrays and you can index them on the table ID (for example) and easily navigate around parent/child relationships without a lot of hassle. I like sparse arrays a lot. Java has them but of course they’re in a utility class, not the language syntax so it’s not that wonderful. It shows the usual thing: you can do anything in any language, just that some have syntax that makes it easier. I’d love a SQL-enabled AWK, for example. The main thing is thinking in abstract structures and then bending the language to fit. If you only have say, VB, then the world (well your brain’s perception of it) is only VB-enabled. You need to learn more to progress; if you have a hammer everything is a nail.

Thinking of going to see a film tonight, was going to go paddling but tiredness pissing me off.

Stories

Started a short story last night; don’t know if it’ll go anywhere but what the hell.

The story so far

Birthdays

I was 44 yesterday. Crap. Not that good a birthday either, as these things go. Bought myself a personal CD player with a car kit so I can listen to my CD collection in the car. Really miss the multichanger in the old car. Ho fkn hum. Spent the day working and driving and trying to sleep. I’m convinced Burger King put caffeine in their Fanta. It’s the only explanation I can find for not being able to sleep. Couldn’t get meditating together today either.

Got a call from an old friend yesterday whom I haven’t seen for at least 12 years. She’s coming to the UK on the 25th so hopefully we can link up.

Catching up

I’m working for a utility company based in Nottingham which is about 100 miles from home. I’ve got a six month contract here and the work is really interesting. The people are good as well. The downside is being away from home 5 nights a week. I’d trade the excellent contract rate for being able to see Rosie and the kids like a shot. I have a blog entry on my laptop but no way of putting it here just yet.

Holme Pierpoint

For those who don’t know this is the National White Water centre and it’s based in Nottingham. I had a paddle there on Tuesday and copped a bad swim. Backrest loose and being cocky. It’s funny how nature humbles you back to the insignificant nothing you really are.

The mind

Was watching the BBC programme about the mind yesterday. Very interesting, all these things starting scientists have discovered that … you can change your personality, you can choose your behaviour, you can learn to be gentle, things are fixed in your childhood but can be altered. Buddhists have known this stuff for two and a half thousand years, without the benefits of MRI scans. Even the bit about the mind being like an orchestra.

Anyway, blessings all, even the dyed geeks.

1st october

So what’s been happening for these last few weeks?

First off, I found a contract job in Nottingham working for a utility company, this is 2 hours from where I live. So I’m back on the road, staying in hotels and not getting enough exercise.

It’s quite odd; I went for a walk today and it all looked very unreal. I’m staying on the edge of town in the Travelodge and there’re all of these buildings lit up from below; proxy country houses built in 1997. It’s like a movie set, underneath, behind it there’s nothing substantial. I wonder if my studying and meditiation practice are having an effect, allowing me to see that there’s nothing there really. It’s not a bad feeling at all, I’m almost getting a sense of completion.

Nottingham has the national white water centre, they’re open until 9 during the week so I’m thinking that I will probably spend a lot of time there.

I went to buy a laptop from my friends at savastore using Rosie’s credit card (it’s new and got a long interest free period). Cocked up the delivery address and couldn’t change it on the web so cancelled. It took 24 hrs to cancel and the card has almost run out of cash so I can’t order again until tomorrow when the credit goes back onto the card.

Unlike the days when I was contracting before there are now umbrella companies that allow you to reclaim your expenses and mitigate (but not avoid) some of the effects of the nasty IR35. I am using a company called prosperity4. The only downside is that I won’t get paid until November and my expenses are pretty extreme, like about £400 a week. Think I’ll have to have a word with my bank manager.

The work at here is very interestng but obviously for reasons of confidentiality I can’t discuss it here. Aggressive deadlines and a large IT infrastructure, oh, how I have missed them in the backwater I was travelling in. My one worry is that I sometimes go a bit passive under pressure and just do what’s fun, so I’m going to have to watch myself.

I met one of my old Oracle colleagues here, Michel, whom I knew from the Halifax project.

I’m having fun and will be able to pay my bills so fuck it, just have to get on with life and make sure it’s worth living. I just wish I could get home at night but that will have to wait until the market picks up.