Pull to refresh

Comments 9

Виноват не знак доллара, а тот, кому лень было сделать по уму через подготовленные запросы с плейсхолдерами. А может и с нормальными полями таблицы вместо jsonb.

Справедливо, корень именно в этом: я собираю SQL строкой. Контекст, который делает это не оправданием, а диагнозом: база живёт в соседнем контейнере, и n8n ходит в неё через один HTTP-эндпоинт, принимающий текст запроса. Плейсхолдерам там негде появиться, пока эндпоинт устроен так.

Надо еще обезопаситься от имени “drop table users”, а то с формированием запроса из строки можно нарваться

Да, это ровно та дыра, и я её не закрыл до конца. Сейчас апостроф удваивается, а доллар из значений я выбрасываю совсем: канал по дороге схлопывает пары, поэтому dollar-quoting в нём неприменим в принципе.

Нода подставляет значение в шаблон, и подстановка идёт через JS-замену. А в строке замены $ — служебный символ.

То есть мои $$ схлопывались в один $ ещё до того, как SQL доходил до Postgres.

следующий человек, который напишет $$ по привычке, наступит туда же.

Так может, перед тем, как передать строку в то место, где $$ схлопывается в $, надо просто перевести все знаки "$" в спецпоследовательности "$$"?

Ваш вариант рабочий, и он честнее моего: если удвоить каждый доллар до подстановки, схлопывание вернёт исходный символ, и данные не пострадают.

Справедливо, "не оправдание, а диагноз", честнее...

Галимый нейрослоп.

Ловушка со спецсимволами в String.prototype.replace довольно тонкий баг на стыке JS и Postgres, про который легко забыть при использовании кавычек $$. Логика fail-closed для дедупликации тут действительно верное решение, а то любой скрытый HTTP 200 от ноды n8n при ошибке SQL гарантированно множит сущности.

Так почему для изоляции базы изначально была выбрана схема с передачей сырого SQL-запроса через вебхук mk-db-exec, а не классический вызов хранимых процедур Postgres, куда JSON с параметрами можно было бы пробрасывать целиком, избегая проблем с шаблонизацией строк на стороне n8n?

Честный ответ: потому что так было быстрее всего в тот вечер, когда мне понадобился доступ к базе из соседнего контейнера. Эндпоинт задумывался как времянка под один запрос, оброс вызовами и остался. Никто, включая меня, не остановился спросить, почему интеграция ходит в базу текстом. Цена — ровно этот класс ошибок на стыке двух языков.

Sign up to leave a comment.

Articles