Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Crossreference to member of aliased container
Crossreference to member of aliased container [message #757576] Sat, 19 November 2011 19:12 Go to next message
Tobias Habermann is currently offline Tobias HabermannFriend
Messages: 9
Registered: July 2009
Junior Member
Hello,

I recently started trying out Xtext and I'm now trying to implement a (small) subset of SQLite for a project. I ran into the following problem for SELECT queries (simplified example):

Quote:

Table:
'CREATE' 'TABLE' name=ID '(' columns+=ColumnDef (',' columns+=ColumnDef)* ')';

Select:
'SELECT' resultColumns+=ResultColumn (',' resultColumns+=ResultColumn)* 'FROM' source=TableSource;

TableSource:
table=[Table | ID] ('AS' alias=ID)?;


And now I am unsure how to implement "ResultColumn".
Quote:

ResultColumn:
tableSource=[TableSource|ID] '.' column=[ColumnDef|ID]

would work, with a ScopeProvider that assigns the TableSource elements with either the referenced table's name or the given alias. But it would break the code completion a bit, because I cannot put a combination like "tableName.columnName" into the scope. I guess I'd have to look into writing a custom ContentAssist then?

The alternative would be
Quote:

ResultColumn:
column=[Column | QualifiedName]

and then create Column-EObjects that have references to the referenced TableSource AND the referenced Column. But I don't really know how this would be done. I guess this problem arises in lots of situations, like referencing a member of a Java-like-instance where the actual Member-EObject would be defined within the class, not the instance. So I'm wondering how this is normally handled, haven't really understood that from reading the documentation so far.

Thanks in advance for any help!

Regards,
Tobias
Re: Crossreference to member of aliased container [message #757581 is a reply to message #757576] Sat, 19 November 2011 21:14 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hi,

i dont get your problem

you have 2 possibilities

(1) you do ResultColumn: tableSource=[TableSource|ID] '.' column=[ColumnDef|ID]
(2) ResultColumn: column=[ColumnDef|QualifiedName]

in (1) you have of course to write first the tablename, then the '.' and then the column name, but i do not see this as a "break of code completion"

in (2) have a look at

Model:
	tables+=Table*
	selects+=Select*;
	
Table:
{Table}'CREATE' 'TABLE' name=ID '(' columns+=ColumnDef (',' columns+=ColumnDef)* ')';

Select:
{Select}'SELECT' resultColumns+=ResultColumn (',' resultColumns+=ResultColumn)* 'FROM' source=TableSource;

ColumnDef:
	name=ID "varchar32"
;

ResultColumn:
column=[ColumnDef | QualifiedName];

QualifiedName: ID "." ID;

TableSource:
table=[Table | ID] ('AS' alias=ID)?;



public class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
	
	IScope scope_ResultColumn_column(Select select, EReference ref) {
		if (select.getSource() != null && select.getSource().getTable() != null) {
			List<IEObjectDescription> scope = new ArrayList<IEObjectDescription>();
			Table table = select.getSource().getTable();
			String alias = select.getSource().getAlias();
			for (ColumnDef col : table.getColumns()) {
				scope.add(EObjectDescription.create(QualifiedName.create(table.getName(), col.getName()), col));
				if (alias != null) {
					scope.add(EObjectDescription.create(QualifiedName.create(alias, col.getName()), col));
				}
			}
			return new SimpleScope(scope);
		} else {
			return IScope.NULLSCOPE;
		}
	}

}


~Christian


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Sat, 19 November 2011 21:18]

Report message to a moderator

Re: Crossreference to member of aliased container [message #757584 is a reply to message #757581] Sat, 19 November 2011 21:32 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Here the solution for the other way

Model:
	tables+=Table*
	selects+=Select*;
	
Table:
{Table}'CREATE' 'TABLE' name=ID '(' columns+=ColumnDef (',' columns+=ColumnDef)* ')';

Select:
{Select}'SELECT' resultColumns+=ResultColumn (',' resultColumns+=ResultColumn)* 'FROM' source=TableSource;

ColumnDef:
	name=ID "varchar32"
;

ResultColumn:
table=[TableSource] "." column=[ColumnDef | ID];

TableSource:
table=[Table | ID] ('AS' alias=ID)?;


public class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
	
	IScope scope_ResultColumn_column(ResultColumn rc, EReference ref) {
		return Scopes.scopeFor(rc.getTable().getTable().getColumns());
	}
	
	IScope scope_ResultColumn_table(Select select, EReference ref) {
		if (select.getSource() != null && select.getSource().getTable() != null) {
			List<IEObjectDescription> scope = new ArrayList<IEObjectDescription>();
			Table table = select.getSource().getTable();
			String alias = select.getSource().getAlias();
			scope.add(EObjectDescription.create(QualifiedName.create(table.getName()), select.getSource()));
			if (alias != null) {
				scope.add(EObjectDescription.create(QualifiedName.create(alias), select.getSource()));
			}
			return new SimpleScope(scope);
		} else {
			return IScope.NULLSCOPE;
		}
	}

}


ca is still a bit tricky with your grammar then


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Crossreference to member of aliased container [message #758284 is a reply to message #757584] Tue, 22 November 2011 14:52 Go to previous message
Tobias Habermann is currently offline Tobias HabermannFriend
Messages: 9
Registered: July 2009
Junior Member
Thank you for your answer. I guess using two references is the way to go then for me, because I need to know which alias/table was used to reference a specific column. In your (2), I would get a reference to the same column EObject, regardless of the actual table name/alias that was used. I now did it like you suggested in the last post, and it works so far.
It does not really "break" ContentAssist, but I'd rather present full "tableName.columnName" combinations in the ContentAssist, because usually there are just one or two tables involved. But I guess I'll try solving that using a customized ContentAssist.
Thanks for the help!

Regards,
Tobias
Previous Topic:Grammar & Scoping Pattern for variables, functions
Next Topic:JVM model inferrer for non-xbase models
Goto Forum:
  


Current Time: Fri Mar 29 05:11:38 GMT 2024

Powered by FUDForum. Page generated in 0.03057 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top