Grammar Question and using unordered groups [message #643398] |
Mon, 06 December 2010 18:25 |
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]
}
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03145 seconds