Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Grammar Question and using unordered groups
Grammar Question and using unordered groups [message #643398] Mon, 06 December 2010 13:25 Go to next message
pozer is currently offline pozer
Messages: 32
Registered: August 2010
Member
I have the following grammar:
grammar org.xtext.querydef.QueryDef with org.eclipse.xtext.common.Terminals

generate queryDef "http://www.xtext.org/querydef/QueryDef"


import "platform:/resource/org.xtext.DefTable/src-gen/org/xtext/example/deftable/DefTable.ecore" as deftable
import "http://www.eclipse.org/emf/2002/Ecore" as ecore


NameSpaces:{NameSpaces}
(namespace+=NameSpace)*;


NameSpace:
'Namespace' name=ID "{"
(query+=Query)*
"}";

Query:
//Query Name
'Query' namespace=[NameSpace] ("." name=QualifiedName)"{"
(


("[" 'Description:' description=MYSTRING"]")//Query Description: This is a sentence describing what the query does. Should include execution time.
("[" 'Set join_collapse_limit=' limit=INT"]")?//Not currently in use: Helps speed up a query when execution plan is faulty
("[" 'Query:'queryName=[NameSpace]'.'query=[Query|QualifiedName]"]")?//When an extension of another query this is the name of the query referred to.
("[" 'Cartridge:' cartridge=MYSTRING "]")?//Name of the Cartridge
("[" 'Filter:' filter+=Filter?(',' filter+=Filter)*"]")?//Refers to the filters: see below for details
("[" 'Return:' return+=ReturnElement (',' return+=ReturnElement)* "]")?//Columns to be returned. see below for details
//("[" 'Case When' caseStatement+=CaseStatement"]")*
("[" 'From:' from=[deftable::Table]//Cross reference to TableDef. Will give you a list of tables for your from clause
joinexpression+=JoinExpression*//Refers to your joins see below for details
"]")?
("[" 'Where:' where+=Where(("And"|"Or")where+=Where)* "]")?//Typical where clause- see below for details
("[" union+=Union "]")?

("[" 'Order:' order+=OrderExpression(',' order+=OrderExpression)*"]")?//Ordering

"}");
//
//Filters must have a qualified column: IE: Action.ActionId, If it is required then * must follow, This can also be a distance field which is not part of a table. Or a fragment, or an aggregate- the aggregate is a prefix with an underscore
Filter: column=(QualifiedTableReference)(multi?='*')?|(distance+=Distance) (multi?='*')?|('MIN_'|'MAX_'|'AVERAGE_'|'RANGE_')column3=QualifiedTableReference(multi?='*')?|fragment+=Fragment (multi?='*')?;//[fragment::Fragments](multi?='*')?;
//Return columns must have a qualified column: IE: Action.ActionId, If it is an aggregate it is followed by .Min or .max or.average etc This can also be a distance field which is not part of a table. Or a fragment, or an aggregate
ReturnElement: column=QualifiedTableReference('As' asname=ID)?|(column2=QualifiedTableReference)'.'('MIN'|'MAX'|'AVERAGE'|'Range'|'Distinct_Count') ('As' asname=ID)?;//|fragment+=Fragment;//fragment=[fragment::Fragments];
ReturnUnionElement:columnunion=QualifiedTableReference('As' asunionname=ID)?|(columnunion2=QualifiedTableReference)'.'('MIN'|'MAX'|'AVERAGE'|'Range'|'Distinct_Count') ('As' asunionname=ID)?;//|fragment+=Fragment;//fragment=[fragment::Fragments];
// A predefined group of columns .  check fragment files for names.
Fragment: '['('ReturnFragment:'|'FilterFragment:') fragname=ID']';

//Distance Choices
enum Distance: radiussearchdistance='RadiusSearchDistance'|radiussearchradius='RadiusSearchRadius'|RadiusSearchDistanceFromLatLon='RadiusSearchDistanceFromLatLon'|RadiusSearchLatLon='RadiusSearchLatLon'|RadiusSearchPostalCode='RadiusSearchPostalCode'|RadiusSearchDistanceFromPostalCode='RadiusSearchDistanceFromPostalCode';


JoinExpression:InnerJoinExpression|OuterJoinExpression;//Definitions of the joins are below

//Inner Joins can be Optional -  Meaning they are only joined to when they are need for filters or results
//Table names and column names are cross reference to Deftables so content assist will give you a list
InnerJoinExpression:
(optional?='Optional')? 'Inner' 'Join' jointablename+=[deftable::Table]
"On" equals+=ColumnRefEqualsExpression
("And" equals+=ColumnRefEqualsExpression)*
(("And"|"Or") equals+=JoinAndExpression)*;

//Left Outer Joins can be Optional -  Meaning they are only joined to when they are need for filters or results
//Table names and column names are cross reference to Deftables so content assist will give you a list
OuterJoinExpression:
(optional?='Optional')? 'Left' 'Join' jointablename=[deftable::Table]
"On" equals+=ColumnRefEqualsExpression
(("And"|"Or") equals+=ColumnEqualsExpression)*//See below for definition
(("And"|"Or") equals+=JoinAndExpression)*//See below for definition

//
//
;
//CaseStatement:  name=STRING;
ColumnEqualsExpression:ColumnRefEqualsExpression|ColumnStringEqualsExpression;
//The ability to join to another table or set a column equal to a string or integer in a join
ColumnRefEqualsExpression: left=QualifiedTableReference '=' 
right=QualifiedTableReference;
ColumnStringEqualsExpression: left=QualifiedTableReference '=' 
right=STRING;

JoinAndExpression:
IntCompareExpression|NullExpression|NotNullExpression|StringEqualsExpression;
//Sets a column equal to whatever expression is needed Ie.int, string, null etc.
Where: "("?column=QualifiedTableReference (expression=WhereExpression)")"?;

//Sorting choose a colum and direction if necessary.  Defaults ascending. Ordering defaults to columns chosen
OrderExpression: column= QualifiedTableReference(direction+=Direction)?;

enum Direction: ascending="asc"|descending="desc";

enum Union: union='Union'|unionAll='Union All';

WhereExpression: 
IntCompareExpression|NullExpression|NotNullExpression|StringEqualsExpression;

NullExpression: "is" "null"{NullExpression};
NotNullExpression: "is" "not" "null"{NotNullExpression};

IntCompareExpression: comparator=Comparator value=INT;
StringEqualsExpression: '=' value=STRING;//|blank=" "
enum Comparator: equals = "="| greater=">"|less="<"| 
lessequals="<="|greaterequals= ">="|notequals="<>";

//Overrides Terminal ID to allow for _ for 
terminal ID  		: '^'?('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9')*;
QualifiedTableReference hidden():element=[deftable::Table]'.'attribute=[deftable::Column];
QualifiedName hidden():ID('.'ID)*;
MYSTRING hidden(): (ID|WS|INT|STRING|'not'|','|ANY_OTHER|'null'|'.'|'Join'|'Inner'|'On'|'='|'or'|'keyword'|'Range'|'MIN'|'MAX'|'AVERAGE')*;


Which then Produces the following dsl:
Namespace PubArticle{
	Query PubArticle.Top.Listings.ByCategorySiteImageType{
	[Description:Get top articles/Images for a specific site and categorys]
	
	[Filter:PubArticleSiteCategorySiteCache.PubArticleSiteCategoryCategory*, PubArticleArticle.SiteId*, PubArticleImageSiteChannelCache.PubArticleImageTypeId*]
	[Return:PubArticleArticle.PubArticleId As PubArticleId,
			PubArticleArticle.SiteId As SiteId,
			PubArticleArticle.PubArticleSlug As PubArticleSlug,
			PubArticleArticle.PubArticleUrl As PubArticleUrl,
			PubArticleSiteCategorySiteCache.PubArticleSiteCategoryCategory As PubArticleSiteCategoryCategory,
			PubArticleImageSiteChannelCache.PubArticleFileMasterId As PubArticleFileMasterId,
			PubArticleImageSiteChannelCache.PubArticleImageTypeId As PubArticleImageTypeId,
			PubArticleImageSiteChannelCache.PubArticleImageFileName As PubArticleImageFileName,
			PubArticleImageSiteChannelCache.PubArticleImageArbitraryPath As PubArticleImageArbitraryPath ,
			PubArticleArticle.PubArticleDatePrintCover]
	[From: PubArticleSiteCategorySiteCache
			Inner Join PubArticleArticle On  PubArticleArticle.PubArticleId=PubArticleSiteCategorySiteCache.PubArticleId  
					And  PubArticleArticle.PubArticleId=PubArticleArticle.PubArticleId 
					And PubArticleSiteCategorySiteCache.SiteId=PubArticleArticle.SiteId
			Inner Join PubArticleImageSiteChannelCache On  PubArticleImageSiteChannelCache.PubArticleId=PubArticleArticle.PubArticleId  
					And  PubArticleSiteCategorySiteCache.SiteId=PubArticleImageSiteChannelCache.SiteId]
	[Where: PubArticleArticle.PubArticleSlug is not null And
			PubArticleImageSiteChannelCache.PubArticleFileMasterId is not null  
			And PubArticleImageSiteChannelCache.PubArticleFileMasterId <> 0 ]
	[Union All]
	

	
		[Order: PubArticleArticle.PubArticleDatePrintCover desc]		 
			
			}
			
			}


What I would like to happen is that if the Union All or Just Union is typed in then the return from and where clauses can be added again with new data. Otherwise it can only be included once. What is the best way for me to do this? Is there a way for me to repeat sections twice? So ultimately I would like to be able to the following sometimes not always. I can't used unordered groups because you only use each one once correct?
Namespace PubArticle{
	Query PubArticle.Top.Listings.ByCategorySiteImageType{
	[Description:Get top articles/Images for a specific site and categorys]
	
	[Filter:PubArticleSiteCategorySiteCache.PubArticleSiteCategoryCategory*, PubArticleArticle.SiteId*, PubArticleImageSiteChannelCache.PubArticleImageTypeId*]
	[Return:PubArticleArticle.PubArticleId As PubArticleId,
			PubArticleArticle.SiteId As SiteId,
			PubArticleArticle.PubArticleSlug As PubArticleSlug,
			PubArticleArticle.PubArticleUrl As PubArticleUrl,
			PubArticleSiteCategorySiteCache.PubArticleSiteCategoryCategory As PubArticleSiteCategoryCategory,
			PubArticleImageSiteChannelCache.PubArticleFileMasterId As PubArticleFileMasterId,
			PubArticleImageSiteChannelCache.PubArticleImageTypeId As PubArticleImageTypeId,
			PubArticleImageSiteChannelCache.PubArticleImageFileName As PubArticleImageFileName,
			PubArticleImageSiteChannelCache.PubArticleImageArbitraryPath As PubArticleImageArbitraryPath ,
			PubArticleArticle.PubArticleDatePrintCover]
	[From: PubArticleSiteCategorySiteCache
			Inner Join PubArticleArticle On  PubArticleArticle.PubArticleId=PubArticleSiteCategorySiteCache.PubArticleId  
					And  PubArticleArticle.PubArticleId=PubArticleArticle.PubArticleId 
					And PubArticleSiteCategorySiteCache.SiteId=PubArticleArticle.SiteId
			Inner Join PubArticleImageSiteChannelCache On  PubArticleImageSiteChannelCache.PubArticleId=PubArticleArticle.PubArticleId  
					And  PubArticleSiteCategorySiteCache.SiteId=PubArticleImageSiteChannelCache.SiteId]
	[Where: PubArticleArticle.PubArticleSlug is not null And
			PubArticleImageSiteChannelCache.PubArticleFileMasterId is not null  
			And PubArticleImageSiteChannelCache.PubArticleFileMasterId <> 0 ]
	[Union All]
	[Return:PubArticleArticle.PubArticleId As PubArticleId,
			PubArticleArticle.SiteId As SiteId,
			PubArticleArticle.PubArticleSlug As PubArticleSlug,
			PubArticleArticle.PubArticleUrl As PubArticleUrl,
			PubArticleSiteCategorySiteCache.PubArticleSiteCategoryCategory As PubArticleSiteCategoryCategory,
			PubArticleImageSiteChannelCache.PubArticleFileMasterId As PubArticleFileMasterId,
			PubArticleImageSiteChannelCache.PubArticleImageTypeId As PubArticleImageTypeId,
			PubArticleImageSiteChannelCache.PubArticleImageFileName As PubArticleImageFileName,
			PubArticleImageSiteChannelCache.PubArticleImageArbitraryPath As PubArticleImageArbitraryPath ,
			PubArticleArticle.PubArticleDatePrintCover]
	[From: PubArticleSiteCategorySiteCache
			Inner Join PubArticleArticle On  PubArticleArticle.PubArticleId=PubArticleSiteCategorySiteCache.PubArticleId  
					And  PubArticleArticle.PubArticleId=PubArticleArticle.PubArticleId 
					And PubArticleSiteCategorySiteCache.SiteId=PubArticleArticle.SiteId
			Inner Join PubArticleImageSiteChannelCache On  PubArticleImageSiteChannelCache.PubArticleId=PubArticleArticle.PubArticleId  
					And  PubArticleSiteCategorySiteCache.SiteId=PubArticleImageSiteChannelCache.SiteId]
	[Where: PubArticleArticle.PubArticleSlug is not null And
			PubArticleImageSiteChannelCache.PubArticleFileMasterId is not null  
			And PubArticleImageSiteChannelCache.PubArticleFileMasterId <> 0 ]

	
		[Order: PubArticleArticle.PubArticleDatePrintCover desc]		 
			
			}
Re: Grammar Question and using unordered groups [message #643509 is a reply to message #643398] Tue, 07 December 2010 03:11 Go to previous messageGo to next message
Alexander Nittka is currently offline Alexander Nittka
Messages: 1151
Registered: July 2009
Senior Member
Hi,

I guess you will have to change the metamodel, making Query a possible union of several subqueries.

//just for illustration
Query: subqueries+=SubQuery (union+=Union subqueries+=SubQuery)*;

or possibly you want to put the union part within the subquery or have different types for union- and unionAll-Subqueries.

Query: //common stuff like description etc.
...subqueries+=SubQuery*;

SubQuery: FirstSubQuery|UnionAllSubQuery|UnionSubQuery;

UnionAllSubQuery: "Union" "All" ...;
UnionSubQuery: "Union"...;
...

Alex
Re: Grammar Question and using unordered groups [message #643627 is a reply to message #643398] Tue, 07 December 2010 11:51 Go to previous message
pozer is currently offline pozer
Messages: 32
Registered: August 2010
Member
Thanks Alex. that gives me some idea of how to approach.
Previous Topic:Invoke validation programmatically
Next Topic:Possible different handling of 'reserved' words
Goto Forum:
  


Current Time: Wed Aug 20 14:35:37 EDT 2014

Powered by FUDForum. Page generated in 0.08715 seconds