Skip to content

Conversation

@marc-dll
Copy link
Contributor

@marc-dll marc-dll commented Oct 31, 2025

FIX: product stock lists: prevent SQL error when filtering on physical stock

Since v22, natural_search() sanitizes (with a call to DoliDB::sanitize()) the list of fields passed in the first argument.

Therefore, using SQL functions on those calls results in SQL errors.

Requête dernier accès en base en erreur: SELECT p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity, p.fk_product_type, p.tms as datem, p.duration, p.tosell as statut, p.tobuy, p.seuil_stock_alerte, p.desiredstock, SUM(s.reel) as stock_physique FROM llx_product as p LEFT JOIN llx_product_stock as s ON p.rowid = s.fk_product WHERE p.entity IN (1) AND EXISTS (SELECT e.rowid FROM llx_entrepot as e WHERE e.rowid = s.fk_entrepot AND e.entity IN (1)) AND p.fk_product_type <> '1' GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity, p.fk_product_type, p.tms, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock HAVING SUMCASEWHENs.reelISNULLTHEN0ELSEs.reelEND > 0 ORDER BY p.ref ASC LIMIT 26
Code retour dernier accès en base en erreur: DB_ERROR_NOSUCHFIELD
Information sur le dernier accès en base en erreur: Unknown column 'SUMCASEWHENs.reelISNULLTHEN0ELSEs.reelEND' in 'HAVING'

In the case we encountered, the error occurs on the HAVING part of the query, so I suggest moving calculations to the SELECT part, and only call natural_search() with the alias of such field.

Moreover, using COALESCE() is cleaner in this case, this function returns the first non-NULL argument it is given, so it simplifies those query elements.

if ($search_stock_physique != '') {
//$natural_search_physique = natural_search('HAVING SUM(' . $db->ifsql('s.reel IS NULL', '0', 's.reel') . ')', $search_stock_physique, 1, 1);
$natural_search_physique = natural_search('SUM(' . $db->ifsql('s.reel IS NULL', '0', 's.reel') . ')', $search_stock_physique, 1, 1);
$natural_search_physique = natural_search('stock_physique', $search_stock_physique, 1, 1);
Copy link
Member

@eldy eldy Nov 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems not SQL portable. Postgesql for example does not allow use ofalias into a having.
A solution would be to to
$natural_search_physique = natural_search('__SUM_OF_REEL__', $search_stock_physique, 1, 1);
then
$natural_search_physique = str_replace('__SUM_OF_REEL__', 'SUM(' . $db->ifsql('s.reel IS NULL', '0', 's.reel') . ')', $natural_search_physique);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eldy Thanks for your feedback, I had forgotten about this specificity of PostgreSQL. PR modified as you suggested.

@eldy eldy added the PR to fix - See feedback in comments PR needs to be fixed to be integrated (some comments should describes the fix to do) label Nov 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR to fix - See feedback in comments PR needs to be fixed to be integrated (some comments should describes the fix to do)

2 participants