Project

General

Profile

Actions

Bug #12378

closed

Error with JOIN in new extension manager

Added by Steffen Kamper almost 14 years ago. Updated almost 10 years ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
Database API (Doctrine DBAL)
Target version:
-
Start date:
2011-01-19
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
7
PHP Version:
Tags:
Complexity:
Is Regression:
No
Sprint Focus:

Description

When i have the repository list and click without searching on column "Relevance" i get the following fatal error from DBAL:

DBAL fatal error: No handler found in handler_getFromTableList() for: "cache_extensions INNER JOIN (SELECT *, MAX(intversion) AS maxintversion FROM cache_extensions GROUP BY extkey) AS cache_extensions2 ON cache_extensions.extkey = cache_extensions2.extkey" (SQL engine parse ERROR: No join table found in parseFromTables()!: near "(SELECT *, MAX(intversion) AS maxintversion FROM c")

It's obvious that DBAL expects tablename for the JOIN, but it's a subquery.
I think this is the first part in core where such subquery is used :)

Actions #1

Updated by Steffen Kamper almost 14 years ago

This is the query that fails

SELECT cache_extensions2.*, count(*) AS versions, cache_extensions2.maxintversion AS maxintversion,(
(CASE WHEN cache_extensions.extkey = "tt_news" THEN 100 ELSE 0 END) +
(CASE WHEN cache_extensions.title = "tt_news" THEN 60 ELSE 0 END) +
(CASE WHEN cache_extensions.extkey LIKE '%tt\_news%' THEN 30 ELSE 0 END) +
(CASE WHEN cache_extensions.title LIKE '%tt\_news%' THEN 10 ELSE 0 END)
) AS relevance FROM cache_extensions INNER JOIN (SELECT *, MAX(intversion) AS maxintversion FROM cache_extensions GROUP BY extkey) AS cache_extensions2 ON cache_extensions.extkey = cache_extensions2.extkey WHERE cache_extensions.repository=1 AND (cache_extensions.extkey LIKE '%tt\_news%' OR cache_extensions.title LIKE '%tt\_news%') GROUP BY cache_extensions.extkey ORDER BY relevance DESC, title DESC LIMIT 0, 50
Actions #2

Updated by Xavier Perseguers almost 14 years ago

I tried to add support for the subquery but actually there's another problem first. The complicated case is not supporter either.

Then, adding support for the subquery itself is much more complicated than it seems as the parser is quite fragile, you should first add an dumb WHERE 1=1 clause to the subquery otherwise the GROUP BY part fails, then the GROUP BY part fails because there's no space before the ending parenthesis but if you add it, parseFieldList() crashes as it seems to it that there is still something to be parsed (for sure, the rest of the "main" query). I could try to remove that test but even with all my unit tests, I fear to have side effects.

:-(

Actions #3

Updated by Jigal van Hemert almost 14 years ago

SELECT cache_extensions.*, count(*) AS versions, MAX(intversion) AS maxintversion,(
    (CASE WHEN cache_extensions.extkey = "font" THEN 100 ELSE 0 END) +
    (CASE WHEN cache_extensions.title = "font" THEN 60 ELSE 0 END) +
    (CASE WHEN cache_extensions.extkey LIKE '%font%' THEN 30 ELSE 0 END) +
    (CASE WHEN cache_extensions.title LIKE '%font%' THEN 10 ELSE 0 END)
) AS relevance 
FROM cache_extensions 
WHERE cache_extensions.repository=1 AND (cache_extensions.extkey LIKE '%font%' OR cache_extensions.title LIKE '%font%') 
GROUP BY cache_extensions.extkey 
ORDER BY title ASC LIMIT 0, 50

Gives me the same result (a few less duplicate fields) on MySQL. I don't know about other DBMS.

I'll try to find a replacement for the the CASE constructions, but at least Oracle knows some form of CASE.

Actions #4

Updated by Xavier Perseguers almost 14 years ago

CASE is officially supported by DBAL and in fact, this could work but the parser is currently still not able to parse that complicated query. Unlike the subquery this seems a bit more feasible but still, I'm not sure this will be possible without some big change in the SQL parser.

Actions #5

Updated by Steffen Kamper almost 14 years ago

thanks to Jigal, i got it without using a subquery. This is the actual query:

SELECT cache_extensions.*, count(*) AS versions, cache_extensions.intversion AS maxintversion,(
(CASE WHEN cache_extensions.extkey = "font" THEN 100 ELSE 0 END) +
(CASE WHEN cache_extensions.title = "font" THEN 60 ELSE 0 END) +
(CASE WHEN cache_extensions.extkey LIKE '%font%' THEN 30 ELSE 0 END) +
(CASE WHEN cache_extensions.title LIKE '%font%' THEN 10 ELSE 0 END)
) AS relevance 
FROM cache_extensions 
JOIN cache_extensions AS ce ON cache_extensions.extkey = ce.extkey 
WHERE cache_extensions.lastversion=1 AND cache_extensions.repository=1 AND (cache_extensions.extkey LIKE '%font%' OR cache_extensions.title LIKE '%font%') 
GROUP BY ce.extkey 
ORDER BY relevance DESC, title DESC LIMIT 0, 50

was a bit tricky to get the latest version record and count of versions correct ;)

Actions #6

Updated by Steffen Kamper almost 14 years ago

r3997 in em branch, you can close this issue

Actions #7

Updated by Xavier Perseguers almost 14 years ago

Actually there is still a bug but it does not show up as before, the list of remote extension is simply always empty.

Problem is to be found in em/classes/database/class.tx_em_database.php, in method getExtensionListFromRepository(). The second query is this one (Oracle) when searching for "news" in the field:

SELECT "cache_extensions".*, count(*) AS "versions", "cache_extensions"."intversion" AS "maxintversion",<br />
CASE WHEN   "cache_extensions"."extkey" = 'news' THEN 100 ELSE 10 END AS "relevance"<br />
FROM "cache_extensions" JOIN "cache_extensions" AS  "ce" ON "cache_extensions"."extkey"="ce"."extkey"<br />
WHERE   "cache_extensions"."lastversion" = 1<br />
   AND  "cache_extensions"."repository" = 1<br />
   AND ((instr(LOWER("cache_extensions"."extkey"), 'news',1,1) > 0) OR  (instr(LOWER("cache_extensions"."title"), 'news',1,1) > 0))<br />
GROUP BY "ce"."extkey"<br />
ORDER BY "cache_extensions"."title" ASC

This is an invalid query for Oracle and it returns an error which in turn is converted into an empty list.

Some hints after first analyze:

- cache_extensions cannot be linked twice without using an alias for the "main" table (before the JOIN)
- AS keyword should (or must?) be omitted for table alias (in join)
- GROUP BY clause is invalid

Actions #8

Updated by Xavier Perseguers almost 14 years ago

  • Status changed from New to Accepted
Actions #9

Updated by Michael Stucki almost 11 years ago

  • Project changed from 329 to TYPO3 Core
Actions #10

Updated by Michael Stucki almost 11 years ago

  • Category set to 999
Actions #11

Updated by Georg Ringer almost 10 years ago

  • Status changed from Accepted to Closed
  • TYPO3 Version set to 7
  • Is Regression set to No

there have been several rewrites of the EM in the meantime. therefore I am closing this issue.

feel free to reopen if still valid in 6.2 or 7.

Actions

Also available in: Atom PDF