I changed the FIELD_TYPE part of /packages/db.c to read:
} else {
switch (field->type) {
case FIELD_TYPE_BIT:
case FIELD_TYPE_TINY:
case FIELD_TYPE_SHORT:
case FIELD_TYPE_DECIMAL:
case FIELD_TYPE_NEWDECIMAL:
case FIELD_TYPE_LONG:
case FIELD_TYPE_INT24:
v->item[i].type = T_NUMBER;
v->item[i].u.number = atoi(target_row[i]);
break;
case FIELD_TYPE_FLOAT:
case FIELD_TYPE_DOUBLE:
v->item[i].type = T_REAL;
v->item[i].u.real = atof(target_row[i]);
break;
case FIELD_TYPE_TINY_BLOB:
case FIELD_TYPE_MEDIUM_BLOB:
case FIELD_TYPE_LONG_BLOB:
case FIELD_TYPE_LONGLONG:
case FIELD_TYPE_BLOB:
case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING:
case FIELD_TYPE_TIMESTAMP:
case FIELD_TYPE_DATE:
case FIELD_TYPE_TIME:
case FIELD_TYPE_NEWDATE:
case FIELD_TYPE_DATETIME:
case FIELD_TYPE_YEAR:
case FIELD_TYPE_ENUM:
case FIELD_TYPE_SET:
case FIELD_TYPE_GEOMETRY:
if (field->flags & BINARY_FLAG) {
#ifndef NO_BUFFER_TYPE
v->item[i].type = T_BUFFER;
v->item[i].u.buf = allocate_buffer(field->max_length);
write_buffer(v->item[i].u.buf, 0, target_row[i], field->max_length);
#else
v->item[i] = const0u;
#endif
} else {
v->item[i].type = T_STRING;
if (target_row[i]) {
v->item[i].subtype = STRING_MALLOC;
v->item[i].u.string = string_copy(target_row[i], "MySQL_fetch");
} else {
v->item[i].subtype = STRING_CONSTANT;
v->item[i].u.string = "";
}
}
break;
case FIELD_TYPE_NULL:
default:
v->item[i] = const0u;
break;
}
}
}
And now "SELECT 'woo', 42, 'foo', COUNT(4)" returns "({ ({ "woo", "42", "foo", "COUNT(4)" }), ({ "woo", UNKNOWN, "foo", UNKNOWN }) })"
So I think i'm getting closer. My guess is that at some point in MySQL development, they added new FIELD_TYPES, and the /packages/db.c hasn't been updated to reflect that.
So this begs the question.. What part of this code returns UNKNOWN as opposed to UNDEFINED in the stock version?