TGViewer
StringConcat - разработка без боли и сожалений StringConcat - разработка без боли и сожалений @stringconcat · 3.72K subscribers
Post #434 2.55K
Энтерпрайз-код 11/10

Небольшой пятничный кек. Коллеги поделились кулстори. Есть некая система, которая ходит к этим самым коллегам по HTTP и периодически присылает кривые жсоны. Например:
{
"id": 123123,
"name": ,
"attr": false
}

То кавычки забудут, то ещё чего.

Как такое возможно, спросите вы? А всё потому, что этот жсон формируется огромным 30-этажным SQL-запросом из coalesce и конкатенаций. Что-то типа:

-- job security 99lvl, LLM себя из розетки выключит увидев такое

SELECT concat('{','"id":',t.id,',','"name":"',coalesce(coalesce(u.name,(select name from users where id=t.user_id and rownum=1)),' '),'",','"attr":',case when row_number() over (partition by t.user_id order by t.created_at) = 1 then lower(cast(t.attr as varchar(10))) else lower(cast(t.attr as varchar(10))) end,',','"settings":{','"lang":"',coalesce(u.lang,(select lang from user_prefs where user_id=t.user_id and rownum=1),'ru'),'",','"theme":',case when u.theme is null then 'null' when u.theme=1 then '"light"' when u.theme=2 then '"dark"' else concat('"',u.theme,'"') end,',','"notifications":',coalesce(cast(u.notif as varchar),(select cast(prefs as varchar) from user_prefs where user_id=t.user_id and rownum=1),'false'),'},','"roles":',(select concat('[',string_agg(concat('"',r.role_name,'"'),','),']') from user_roles r where r.user_id=u.id group by r.user_id),',','"history":{','"prev_name":"',lag(u.name) over (partition by t.user_id order by t.created_at desc),'",','"next_name":"',lead(u.name) over (partition by t.user_id order by t.created_at desc),'"},','"recursive_check":',case when t.id=(select max(id) from requests where user_id=t.user_id) then concat('"FINALLY_',t.id,'"') else concat('"NOT_FINALLY_',(select concat('SUB_',t2.id) from requests t2 where t2.user_id=t.user_id and rownum=1),'"') end,case when exists(select 1 from dual where t.id>0) then ',' else '' end,'}','}') as json_response FROM requests t left join users u on t.user_id=u.id where t.status='active' and row_number() over (order by t.created_at)>0 order by t.created_at desc


Я даже не знаю, как это комментировать и сколько SQL-инъекций с прочими уязвимостями сидит в такой конструкции. Зато теперь понятно, почему на просьбу добавить новое поле они реагируют так нервно.

В общем, отдать JSON прямо из базы можно через какой-нибудь json_agg, но не напрямую же (наверное, это будет недостаточно энтерпрайзно, да и админа БД просто так, что ли, нанимали?)
  • 😁 51
  • 🙈 11
  • 😈 3
  • 🆒 3
  • ❤ 2
  • 🔥 2
  • 👏 1
More from @stringconcat
  1. Sep 26, 2026Вы не заметили, но в интернетах разразился скандал вселенского масштаба. Вопрос вот в чём:…
  2. Sep 21, 2026А сегодня снова не совсем обычный пост (пока я занят написанием духоты). Знаю, что у многи…
  3. Sep 18, 2026Сегодня необычный выпуск — подкаст с нашим старым бро Константином Могилевкиным. Константи…
  4. Sep 15, 2026Я частенько в своих постах упоминаю ключевую характеристику для сотрудника — автономность.…
  5. Sep 8, 2026Продолжаем обзор микросервисных изделий. На этот раз подписчики прислали мне архитектуру,…
  6. Sep 4, 2026Начинаем сезон видосиков с обзора карьерных путей (не переживайте, духота тоже будет, но п…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →