KATOエンジニヤリング開発日誌

「アウトプット無きエンジニアにインプットもチャンスも無い」の精神で書いています

node.jsのsquelがバグってる?と思ったらやるべき対処法

f:id:masayuki_kato:20170215235634j:plain

先日、私の職場である問題が起きた。

それはnode.jsのsquelというモジュールのバグが原因だった。

squelの開発者に対してそのバグのissueがあがっているが、

特に対応もとられず1年以上経過しているため何らかの解決策を探す必要がでてきた。

今日は、そのバグを解決した対応法を記録しておきます。

squelのorderとunionを使用するとおかしな挙動をする

バグは、私が作成したルーチンのテストを実施しているときに発見した。

バグの内容は上記のissueに書かれているように、

「ORDER BY」でソートしているクエリに対して、「UNION」で結合する際に起きるものだ。

squelで下記のようにコーディングすると

var squel = require('squel').useFlavour('postgres');
var q = squel
.select().from('table1')
.order('date')
.union(
    squel.select().from('table2')
);
console.log(q.toString())

こういうクエリ結果を期待しているが

SELECT
    *
FROM
    table_1
ORDER BY
    date ASC
UNION
SELECT
    *
FROM
    table_2

実際はこういうクエリ結果になってしまうというものだった。

SELECT
    *
FROM
    table_1
UNION
SELECT
    *
FROM
    table_2
ORDER BY
    date ASC

それは、中間に入れているorder by句が、squelの「toparam」関数を実行するとクエリの末尾についてしまうものだった。

squelモジュールのバグだとわかった

githubにあるsequelのブランチに同じバグが発生しているというissueを発見した。

github.com

1年前からissueがあがっているが特に反応はない。

なので対処法を自分らで考えなければいけなかった。

バグの対処法

「toParam()」関数でクエリ文字列を生成後に、「text」プロパティに「ORDER BY」句の文字列を結合させるという方法と試してみた。

得られたクエリ文は期待通りだった。

SELECT
    *
FROM
    table_1
ORDER BY
    date ASC
UNION
SELECT
    *
FROM
    table_2

SQLインジェクション等の脆弱性が心配されたが、チームで調査した結果問題ないと判断した。