Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Funny BUG and Serious ISSUE
Message
General information
Forum:
Visual FoxPro
Category:
Databases,Tables, Views, Indexing and SQL syntax
Title:
Funny BUG and Serious ISSUE
Environment versions
Visual FoxPro:
VFP 9
Miscellaneous
Thread ID:
01001002
Message ID:
01001002
Views:
65
Start point: VFP9 don't support EXISTS() into a FIELD computation
explain code:
CLEAR
CLOSE DATABASES ALL
CLOSE TABLES ALL

CREATE CURSOR tree (id I,parentId I NULL)
INSERT INTO tree VALUES (1,NULL)
INSERT INTO tree VALUES (2,NULL)
INSERT INTO tree VALUES (3,1)
INSERT INTO tree VALUES (4,1)
INSERT INTO tree VALUES (5,2)
INDEX ON parentId	TAG rk
* now i want the table: node, hasChild
SELECT ;
	id;
,	EXISTS(SELECT*FROM tree WHERE parentId=T.id) hasChild; && this can to be OPTIMIZED into a simple KEYMATCH(T.id,'rk')
	FROM tree T
	
* FIRST WORKAROUND
CREATE CURSOR PivotConstant (_ L)
APPEND BLANK 

* AT this point I FOUND A FUNNY BUG HERE: 
* TWO CARTESIAN PRODUCTS, AND THE QUERY RETURN 25 rows !
*SYS(3054,11)
SELECT ;
	id;
,	!ISNULL((SELECT .T. FROM PivotConstant WHERE EXISTS(SELECT*FROM tree WHERE parentId=T.id))) hasChild;
	FROM tree T
*SYS(3054,0)
* then I CAN JOY with this: 125
SELECT ;
	id;
,	!ISNULL((SELECT .T. FROM PivotConstant;
		WHERE EXISTS(SELECT*FROM tree WHERE parentId=T.id);
		AND   EXISTS(SELECT*FROM tree WHERE parentId=T.id))) hasChild;
	FROM tree T
* 625 rows
SELECT ;
	id;
,	!ISNULL((SELECT .T. FROM PivotConstant;
		WHERE EXISTS(SELECT*FROM tree WHERE parentId=T.id);
		AND   EXISTS(SELECT*FROM tree WHERE parentId=T.id);
		AND   EXISTS(SELECT*FROM tree WHERE parentId=T.id))) hasChild;
	FROM tree T
* ....

* Now i return to the true issue, and the only workarounds that I'm able to found are

FOR k=6 TO 1000
	INSERT INTO tree VALUES (m.k,IIF(RAND()>0.05,RAND()*M.K,NULL))
NEXT

* A) field subquery with grouping
*    this is more (2x respect to C)) slow because, uses the rk index
*    but after do another join with a temp index
*    it build a join table

? "FIELD SUBQUERY WITH GROUPING"
T1=SECONDS()
SYS(3054,11)
SELECT ;
	id;
,	!ISNULL((SELECT MAX(.T.) FROM tree WHERE parentId=T.id)) hasChild;
INTO CURSOR _R1;
	FROM tree T
SYS(3054,0)
? SECONDS()-T1,_TALLY

* B) field subquery with TOP 1 IS NOT SUPPORTED, but this is not necessary
SELECT ;
	id;
,	!ISNULL((SELECT TOP 1 parentId FROM tree WHERE parentId=T.id ORDER BY 1)) hasChild;
	FROM tree T
	
* C) OUTER JOIN into a grouping subquery,
*    this is slow because, 
*      VFP don't uses a valid index for grouping
*      VFP have to build a temp index for do the OUTER JOIN
? "OUTER JOIN WITH DISTINCT: THIS IS THE BEST WITH A LITTLE TABLE"
T1=SECONDS()
SYS(3054,11)
SELECT ;
	id;
,	!ISNULL(EXISTS.parentId) hasChild;
INTO CURSOR _R2;
	FROM tree T LEFT JOIN (SELECT DISTINCT parentId FROM tree) EXISTS ON EXISTS.parentId=T.id
SYS(3054,0)
? SECONDS()-T1,_TALLY

? "OUTER JOIN WITH GROUPING: THIS IS THE BEST WITH A BIG TABLE"
T1=SECONDS()
SYS(3054,11)
SELECT ;
	id;
,	!ISNULL(EXISTS.parentId) hasChild;
INTO CURSOR _R3;
	FROM tree T LEFT JOIN (SELECT parentId FROM tree GROUP BY 1) EXISTS ON EXISTS.parentId=T.id
SYS(3054,0)
? SECONDS()-T1,_TALLY
Fabio
Next
Reply
Map
View

Click here to load this message in the networking platform