Sqlite pitfall
i wanted to store a set of prime numbers together with other data. So i turned to my database of choice,
sqlite3. Since sqlite has a tendency to automatically convert stuff into other stuff (flexible typing), i set the type for theprimeexplicitly toTEXT, because (quoted from flexible typing)So:Note that an
INTEGERorREALvalue will never end up being stored in aTEXTcolumn, since anINTEGERorREALvalue can and always will be converted into its equivalentTEXTrepresentation.CREATE TABLE IF NOT EXISTS primes ( id INTEGER PRIMARY KEY, prime TEXT UNIQUE ON CONFLICT IGNORE, T INTEGER, k FLOAT); INSERT INTO PRIMES (prime, T, k) VALUES ( 736967235538117954978726019337077632830443, 1234, 0.5); SELECT * FROM primes;But this unexpectedly returns1|7.36967235538118e+41|1234|0.5So the
INSERTsilently (and contrarily to the documentation) converts the prime into a boring, inexactfloat.The fault lies partly with me, since it should have been
INSERT INTO PRIMES (prime, T, k) VALUES ( '736967235538117954978726019337077632830443', 1234, 0.5);(notice the quotes around the prime). But i would have expected an error when inserting an unquoted series of digits into a
TEXTcolumn.It is possible (but not well documented ) to have
sqlite3throw errors in this case, by adding a (non-SQL-standard)STRICTat the end of theCREATE TABLEstatement (as in “I put types on this table, and this time I really mean it”).
Tue, 04 Nov 2025
[/osfail]
permanent link
Programming Pearls: malloc, the Zabbix way
The Zabbix sources define
zbx_mallocininclude/common.h: line 700as:#define zbx_malloc(old, size) zbx_malloc2(__FILE__, __LINE__, old, size)
zbx_malloc2is defined insrc/libs/zbxcommon/misc.c: line 255as:void *zbx_malloc2(const char *filename, int line, void *old, size_t size) { int max_attempts; void *ptr = NULL; /* old pointer must be NULL */ if (NULL != old) { zabbix_log(LOG_LEVEL_CRIT, "[file:%s,line:%d] zbx_malloc: " "allocating already allocated memory. " "Please report this to Zabbix developers.", filename, line); /* exit if defined DEBUG, ignore otherwise */ zbx_dbg_assert(0); } for ( max_attempts = 10, size = MAX(size, 1); 0 < max_attempts && NULL == ptr; ptr = malloc(size), max_attempts-- ); if (NULL != ptr) return ptr; zabbix_log(LOG_LEVEL_CRIT, "[file:%s,line:%d] zbx_malloc: out of memory." "Requested " ZBX_FS_SIZE_T " bytes.", filename, line, (zbx_fs_size_t)size); exit(FAIL); }So where're the pearls in this?
the
oldparameter is forced to beNULL, so why pass it at all???noticed the
forloop? It tries tomallocten times before giving up. This seems to assume that some concurrently running part of zabbixfrees memory, or that the system suddenly (while this loop is running, that is) assigns a higher memory bound for zabbix.noticed the MAX in the
forloop? It tries to catch and disguise the error of requesting zero bytes by always returning at least one byte
Fri, 05 Apr 2013
[/osfail]
permanent link
MySQL cannot erase data
For eight years it has been known (and
This is a veritable showstopper.Verified) that MySQL does not release diskspace it has claimed in itsibdatax files. The bug leads to full disks and database outages since the only way arround it is to shut down the DB, dump it (consuming even more space) scrubbing the disk and restoring from dump.
Fri, 13 Jan 2012
[/osfail]
permanent link
OpenLDAP WTF
Since NIS has seen its hayday (in the early 90ies), we switched to the highly secure LDAP+Kerberos setup. OpenLDAP is touted as the allround “Solution” to all user account management, sorry, I meant to say account provisioning. After converting our NIS
passwdfile to thousands of LDIF files we imported them with the obvious three-linerfor i in *ldif; do \ ldapadd -v -W -D "cn=admin,dc=our,dc=domain" \ -c -H ldapi:/// -f $i doneAfter fiddling with half a dozen files in
/etc, the client systems could look up user data on the LDAP server. Our test for that wasSo it seemed plausible to create a list of all users bygetent passwd aknownuser getent passwd anotherknownuserand install that as a list of valid recipients of e-mails.getent passwd | awk -F: '{print $1}' > allourusersThis was a grave error, because one of the manymany default settings of OpenLDAP is to return only the first 500 answers to any request. So the list was short by a few hundred accounts.
Considering that LDAP has no concept of a cursor and one cannot ask for the next 500 entries, one can only ask
What the fsck were they thinking???
Mon, 28 Nov 2011
[/osfail]
permanent link
Including by explicitly excluding files in Bacula
Bacula's config file format allows the followingFileSet { Name = Blah Exclude { Options { wilddir = /var/tmp* } } File = /var }The Directory
/var/tmpfrom the Exclude section is included in the backup, because to exclude it, the proper config would be
FileSet { Name = Blah Exclude { Options { wilddir = /var/tmp* } exclude = yes } File = /var }
Tue, 25 Jan 2011
[/osfail]
permanent link