111 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			111 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								:- module(myddas_prolog2sql_optimizer,[
							 | 
						||
| 
								 | 
							
												       optimize_sql/2
							 | 
						||
| 
								 | 
							
												      ]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- use_module(lists,[
							 | 
						||
| 
								 | 
							
										     append/3,
							 | 
						||
| 
								 | 
							
										     member/2,
							 | 
						||
| 
								 | 
							
										     delete/3,
							 | 
						||
| 
								 | 
							
										     substitute/4
							 | 
						||
| 
								 | 
							
										     ]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								optimize_sql([],[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								optimize_sql([query(Proj,From,Where)|Tail],[query(Proj1,From1,Where1)|SQLTerm]):-
							 | 
						||
| 
								 | 
							
									optimize_subquery(Proj,Proj1,From,From1,Where,Where1),
							 | 
						||
| 
								 | 
							
									optimize_sql(Tail,SQLTerm).
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								% --- optimize_subquery(SQLFrom,SQLWhere) -------------------------------
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%    If there is a subquery on the query,
							 | 
						||
| 
								 | 
							
								%    uses the less number of table necessary in the
							 | 
						||
| 
								 | 
							
								%    FROM token of the SQL Statement. see(EXPLAIN (SQL statemente with subquerie) ) 
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%    Optimization: * All variables on the projection term must be on the outer statement
							 | 
						||
| 
								 | 
							
								%                  * All variables on the outer query, must have their respective raltions on the outer query
							 | 
						||
| 
								 | 
							
								%                  * Try to maintain as more possibles relations on the inner statement
							 | 
						||
| 
								 | 
							
								% --------------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%TODO: BUG
							 | 
						||
| 
								 | 
							
								%      BEWARE WHEN THE SUBQUERY HAS NO TABLES AT THE END OF THIS OPTIMIZATION
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								optimize_subquery(SQLSelect,OptSelectFinal,F,F,W,W):-
							 | 
						||
| 
								 | 
							
									once(member(agg_query(Agg,Select,From,Where,Extra),SQLSelect)),!,
							 | 
						||
| 
								 | 
							
									optimize_subquery(Select,OptSelect,From,OptFrom,Where,OptWhere),
							 | 
						||
| 
								 | 
							
									substitute(agg_query(Agg,Select,From,Where,Extra),SQLSelect,agg_query(Agg,OptSelect,OptFrom,OptWhere,Extra),OptSelectFinal).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								optimize_subquery(SQLSelect,SQLSelect,SQLFrom,OptFrom,SQLWhere,OptWhere):-
							 | 
						||
| 
								 | 
							
									%SQLSelect = OptSelect,  % In the future, if needed optimize projection term
							 | 
						||
| 
								 | 
							
									once(member(negated_existential_subquery(_,SubQueryRelations,_),SQLWhere))
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
									once(member(existential_subquery(_,SubQueryRelations,_),SQLWhere))
							 | 
						||
| 
								 | 
							
									,!,
							 | 
						||
| 
								 | 
							
									add_relation(SubQueryRelations,[],RelTotalTemp),
							 | 
						||
| 
								 | 
							
									add_relation(SQLFrom,RelTotalTemp,RelTotal),
							 | 
						||
| 
								 | 
							
									projection_term_analysis(SQLSelect,From1,RelTotal,RelTotal1),
							 | 
						||
| 
								 | 
							
									comparasion_analysis(SQLWhere,From1,From2,RelTotal1,RelTotal2),
							 | 
						||
| 
								 | 
							
									delete_surplous_tables(SQLWhere,RelTotal2,OptWhere),
							 | 
						||
| 
								 | 
							
									OptFrom = From2.
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								optimize_subquery(ProjTerm,ProjTerm,From,From,Where,Where).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_surplous_tables([negated_existential_subquery(A,_,B)|T],Rel,[negated_existential_subquery(A,Rel,B)|T]):-!.
							 | 
						||
| 
								 | 
							
								delete_surplous_tables([existential_subquery(A,_,B)|T],Rel,[existential_subquery(A,Rel,B)|T]):-!.
							 | 
						||
| 
								 | 
							
								delete_surplous_tables([H|T],Rel,[H|Final]):-
							 | 
						||
| 
								 | 
							
									delete_surplous_tables(T,Rel,Final).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								comparasion_analysis([],From,From,RelTotal,RelTotal).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								comparasion_analysis([comp(att(Relation,_),_,att(Relation,_))|Tail],From1,[rel(Name,Relation)|FromFinal],RelTotal,RelTotalFinal):-
							 | 
						||
| 
								 | 
							
									member(rel(Name,Relation),RelTotal),!,
							 | 
						||
| 
								 | 
							
									delete(RelTotal,rel(Name,Relation),RelTotal1),
							 | 
						||
| 
								 | 
							
									comparasion_analysis(Tail,From1,FromFinal,RelTotal1,RelTotalFinal).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								comparasion_analysis([comp(att(Relation1,_),_,att(Relation2,_))|Tail],From1,From4,RelTotal,RelTotal3):-
							 | 
						||
| 
								 | 
							
									comparasion_analysis(Tail,From1,From2,RelTotal,RelTotal1),
							 | 
						||
| 
								 | 
							
									!,
							 | 
						||
| 
								 | 
							
									(member(rel(Name,Relation1),RelTotal1) ->
							 | 
						||
| 
								 | 
							
									    delete(RelTotal1,rel(Name,Relation1),RelTotal2),
							 | 
						||
| 
								 | 
							
									    From3 = [rel(Name,Relation1)|From2]
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
									    RelTotal2 = RelTotal1,
							 | 
						||
| 
								 | 
							
									    From3 = From2
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									(member(rel(Name,Relation2),RelTotal2) ->
							 | 
						||
| 
								 | 
							
									    delete(RelTotal2,rel(Name,Relation1),RelTotal3),
							 | 
						||
| 
								 | 
							
									    From4 = [rel(Name,Relation2)|From3]
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
									    RelTotal3 = RelTotal2,
							 | 
						||
| 
								 | 
							
									    From4 = From3
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								comparasion_analysis([_|Tail],From,FromFinal,RelTotal,RelTotalFinal):-
							 | 
						||
| 
								 | 
							
									comparasion_analysis(Tail,From,FromFinal,RelTotal,RelTotalFinal).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								projection_term_analysis([],[],Relation,Relation).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								projection_term_analysis([att(Relation,_)|Tail],[rel(Name,Relation)|FromFinal],RelTotal,RelTotal1):-
							 | 
						||
| 
								 | 
							
									member(rel(Name,Relation),RelTotal),!,
							 | 
						||
| 
								 | 
							
									delete(RelTotal,rel(Name,Relation),Residue),
							 | 
						||
| 
								 | 
							
									projection_term_analysis(Tail,FromFinal,Residue,RelTotal1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								projection_term_analysis([_|Tail],FromFinal,RelTotal,RelTotal1):-
							 | 
						||
| 
								 | 
							
									projection_term_analysis(Tail,FromFinal,RelTotal,RelTotal1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_relation([],Final,Final).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_relation([Rel|Tail],RelTotal,RelFinal):-
							 | 
						||
| 
								 | 
							
									not once(member(Rel,RelTotal)),!,
							 | 
						||
| 
								 | 
							
									append(RelTotal,[Rel],RelTemp),
							 | 
						||
| 
								 | 
							
									add_relation(Tail,RelTemp,RelFinal).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_relation([_|Tail],RelTotal,RelFinal):-
							 | 
						||
| 
								 | 
							
									add_relation(Tail,RelTotal,RelFinal).
							 |