Need help with alternative choices in a rule [message #648450] |
Wed, 12 January 2011 23:06 |
pozer Messages: 32 Registered: August 2010 |
Member |
|
|
I have the following grammar. Please excuse the length of the code:
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.
("[" 'ExpectedCallTimeMS:' calltime=INT "]")// execution time in Milliseconds. Based on dev.
("[" '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
("[" '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)('_MIN'|'_MAX'|'_AVERAGE'|'_RANGE'|'_EXCLUDE')?(multi?='*')?|(distance+=Distance) (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: distance+=Distance|column=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'|distance='Distance';
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|distance+=Distance) (expression=WhereExpression)")"?;
//Sorting choose a colum and direction if necessary. Defaults ascending. Ordering defaults to columns chosen
OrderExpression:{OrderExpression} (column= QualifiedTableReference|distance+=Distance)(direction+=Direction)?;
enum Direction: ascending="asc"|descending="desc";
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 :ID('.'ID)*;
//SubQueryName: subQuery+=[SubQuery]('.')name=ID;
MYSTRING hidden(): (ID|WS|INT|STRING|'not'|','|ANY_OTHER|'null'|'.'|'Join'|'Inner'|'On'|'='|'or'|'keyword'|'RANGE'|'MIN'|'MAX'|'AVERAGE'|'AND'|'DISTINCT_COUNT'|'_'|'('|')'|'And'|'As')*;
And here is what I want my Output:
Query PubArticle.Top.Articles.ByCategorySite{
[Description:Get top 2 articles by Category and Site]
[ExpectedCallTimeMS:0]
[Return:Foo.PubArticleSiteCategoryCategory,]
PubArticleArticle.PubArticlePromoTitle,
PubArticleArticle.PubArticlePromoTeaserLarge,
PubArticleArticle.PubArticleId As PubArticleId,
PubArticleArticle.SiteId As SiteId,
PubArticleArticle.PubArticleSlug As PubArticleSlug,
PubArticleArticle.PubArticleUrl As PubArticleUrl
]
[From:
( Select row_number()over (partition by PubArticleSiteCategoryCategory,PubArticleSiteCategorySiteCache.SiteId order by PubArticleDatePrintCover ) As rownumber,
PubArticleSiteCategoryCategory, PubArticleARticle.PubArticleId
from PubArticleSiteCategorySiteCache
Join PubArticleARticle on PubArticleSiteCategorySiteCache.PubaRticleId=PubARticleARticle.PubARticleId
)As foo
Join PubArticleArticle On Foo.PubArticleId=PubArticleArticle.PubArticleId
]
[Where: [COLOR=red]Foo.rownumber[/COLOR]<3]
[Order: Foo.PubArticleSiteCategoryCategory desc]
}
The question is how do I define the subquery so that I can reference it in the return, where, and order by elements. The contents of the subquery are extremely varied. All the parts I am describing are called FOO above.
If anyone has any ideas it would be greatly appreciated.
[Updated on: Wed, 12 January 2011 23:07] Report message to a moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.02854 seconds