google/lovefield

orderBy() sorts column of lf.Type.INTEGER as a string

fezzzza opened this issue · 2 comments

I think this one is simple to reproduce. My schema looks like this

schemaBuilder.createTable('reasons_fields_links')
.addColumn('id', lf.Type.INTEGER)
.addColumn('reason_link', lf.Type.INTEGER)
.addColumn('field_link', lf.Type.INTEGER)
.addColumn('ordinal', lf.Type.INTEGER)
.addColumn('created_timestamp', lf.Type.INTEGER)
.addColumn('modified_timestamp', lf.Type.INTEGER)
.addColumn('modified_session_link', lf.Type.INTEGER)
.addNullable(['reason_link','field_link','ordinal','created_timestamp','modified_timestamp','modified_session_link'])
.addPrimaryKey(['id'])
;

and my test code looks like this:

function test1(){
	var sql=db.select().from(db_reasons_fields_links)
			.orderBy(db_reasons_fields_links.ordinal)
			.exec()
			.then(function(rows){
					for (row in rows){
						console.log(rows[row].ordinal);
					}
			});
}

the results come out in order of the "ordinal" column, but in string order, eg:
1,11,12,13,2,21,220,2300,3,31,32,33 etc

I have tried using .addIndex('ordinal_idx',['ordinal']) to the schema but the behaviour is the same.

I also see the same behaviour with or without lf.Order.ASC and lf.Order.DESC

Are you sure that you are populating the ordinal column with numerical values and not with strings? Usually what you describe is just a symptom of populating the column with wrong type of data. Note that Lovefield purposefully (for performance reasons) does not check that you actually store JS numbers on a INTEGER column, nor does it automatically convert strings to numbers.

I've checked and you are correct. The default JSON encoding from the server encodes everything as strings and I assumed that assigning lf.Type.INTEGER had a purpose - either for type conversion on .insertOrReplace() or to inform how to sort in .orderBy(). Bad assumption, I guess. I'm now sending numerically-checked JSON before .insertOrReplace() and the ordering now functions as expected. Thanks.