The Advisory Boar

By Abhijit Menon-Sen <>

Spam sent through The Hindu web site

I just received a Nigerian scam email sent through some "forward this article" feature on The Hindu web site.

Read more…

Switching from RSS to Atom

I switched the format of the feed for posts on this web site.

Read more…

No visa required?

The Economist says that as of August 2010, Indian citizens can visit (approximately) 50 "countries and territories" without a visa.

Read more…

A new server at Hetzner.DE

I migrated from one dedicated server at Hetzner to another, and everyone must know all of the fascinating details thereof!

Read more…

Rohan Chakravarty is an excellent cartoonist

I commissioned a couple of illustrations for my web site from Rohan, and he did a great job.

Read more…

Returning records from PL/PgSQL

I needed to write a plpgsql function that inserted rows into some tables and returned the generated primary key values to the caller. I had never needed to return multiple values from a function before, and I ran into a couple of new problems along the way.

This was my first attempt:

create function create_widget(name text, colour int) returns record as $$
declare
    wid int;
    cid int;
    ids record;
begin
    insert into widgets (name) values (name)
        returning widget_id into wid;
    insert into widget_colours (widget_id, colour)
        values (wid, colour)
        returning colour_id into cid;
    select wid::int, cid::int into ids;
    return ids;
end;
$$ language plpgsql;

When I tried this, I got a syntax error which I eventually understood to mean that my parameters could not have the same names as any columns in the table I was inserting into. Not very surprising, since the inserts look a bit ambiguous even when reading the code. Since parameter names occur only in the function definition and aren't exposed to the caller, I didn't mind working around this by renaming my parameters "p_name" and "p_colour".

What did surprise me was that I had to call the function like this:

select * from create_widget('x', 3) as cw(widget_id int, colour_id int);

In other words, the caller always had to supply a column definition list, and I couldn't (see any way to) specify what I was going to return in the function definition.

I was given two suggestions about how to work around this problem. The first was to use OUT parameters:

create function create_widget(name text, colour int,
                              widget_id OUT int, colour_id OUT int)

But this approach, predictably enough, had the same problem with the names of parameters conflicting with the names of columns, and I was much less willing to force the caller to retrieve and have to use columns named "r_widget_id" or something similar.

With Postgres 8.4 and above, I learned that I could also declare the function as returning a table, which looked exactly like what I had hoped for:

create function create_widget(name text, colour int)
    returns table (widget_id int, colour_id int)

But to my great disappointment, the conflict with the column names persists even in this form.

In the end, I decided to use "p_" prefixed parameter names, return a record, and name the columns in the caller.

Mojolicious and X-Powered-By

A few days ago, I discovered that Mojolicious::Plugin::PoweredBy is enabled by default, and adds an "X-Powered-By: Mojolicious (Perl)" header to all HTTP responses. Although I can change the value of the header, there is no way to suppress it (e.g. by setting the value to undef). Since X-headers are meant for private experiments, and should not be exposed to the Internet (never mind how many people do it anyway), I thought this was poor behaviour.

The solution was to bundle an empty PoweredBy plugin with my app:

package Mojolicious::Plugin::PoweredBy;

use base 'Mojolicious::Plugin';

sub register {
}

1;

I brought this up in #mojo on IRC, suggesting tactfully that the plugin should either not be enabled by default, or be easier to disable (when what I really wanted was to suggest it be removed entirely). The Mojo author disagreed, and said that nobody would enable it if it wasn't enabled by default (which is quite true, and to me suggests that it should not exist at all), and that it was "advertising" for Mojo.

It may be advertising, but I'm not sure it sends the right message.

Off we go to Consumer court

After our unpleasant experience with trying to have a faulty Exide battery replaced under warranty, Hassath and I didn't want to let the matter slide, and decided to approach the consumer court.

Under the Consumer Protection Act of 1986, a number of quasi-judicial bodies empowered to deal with consumer grievances have been set up at the district and state level, under an apex body in Delhi called the National Consumer Dispute Redressal Commission; in this case, the East Delhi District Consumer Forum was the most appropriate forum for our complaint.

We spoke to someone at the DCF on the phone, and were told to bring two copies of our petition to them the next day. We spent a couple of hours preparing the petition (following an example on the NCDRC web site) and assembling a paper trail to establish our case (warranty cards, reports of the inspection, email correspondence). We stopped by the Post Office to get a blank Postal Order for INR 100 (the filing fee), and submitted all of this documentation to the (very pleasant) officer at the DCF the next afternoon.

He asked us to pick a date for the initial filing, and we decided on the tenth of August—which happened to be when the warranty of our batteries expired. We were told to appear in court at 10:30 on that morning, for the case to be brought before the Forum and admitted (or thrown out).

We went to court this morning, waited around for a while, and were quite surprised to hear my name called first (the invoice for the purchase of the batteries was in my name, so it was my name on the petition). Two of the Forum's three judges in attendance, and they were handling cases in parallel. I was called by the (stern-looking, but very kind) lady judge, and asked to explain the case. She listened to me, reviewed the petition briefly, and told me to add the battery vendor as an opposing party in the case (our petition named only Exide). Fortunately, I had a complete extra set of all the documentation with me, and she allowed me to just scribble an extra name and address on all three copies.

In the end, she assigned a date one month later, and ordered notices to be sent to the two opposing parties. Now we have to turn up in court on the new date, and we'll see what Exide does by way of opposition.

Trying out Mojolicious

A brief account of how I came to select Mojolicious as my Perl framework of choice to develop web applications. I've been a happy user for years now.

Read more…

Trip report: Basai, 2010-08-01

At the end of a hectic and stressful week, Hassath and I spent a pleasant morning at Basai.

Read more…