public object Translate(TranslationContext context, ASTNode node) { var unaryExpression = new Model.UnaryExpression(); unaryExpression.Instruction = "iExists"; unaryExpression.Expression = SQLTranslationUtilities.EnsureSelectStatementExpression(context.TranslateNode(node.Children[0])); return unaryExpression; }
public object Translate(TranslationContext context, ASTNode node) { var requestListType = node.ResultType as ListType; var requestType = (requestListType == null ? node.ResultType : requestListType.ElementType) as ObjectType; if (requestType == null) { throw new InvalidOperationException(String.Format("Unable to determine request type from source type: '{0}'.", node.ResultType.Name)); } Model.Expression condition = null; // Translate Codes var codes = node.Children.Where(n => n.Name == "codes").FirstOrDefault(); if (codes != null) { var codesResult = context.TranslateNode(codes); // codesResult will be a select statement returning the list of codes // So the retrieve must include a where condition limiting the code property to the set of codes (same as InValueSet translation) var codeExpression = SQLTranslationUtilities.ResolvePath(node.GetAttribute<string>("codeProperty"), "T"); var selectExpression = (SQLModel.SelectExpression)codesResult; // This assumes the codes element is a ValueSetRef... selectExpression.WhereClause.Expression = new Model.BinaryExpression ( selectExpression.WhereClause.Expression, "iAnd", new Model.BinaryExpression(codeExpression, "iEqual", new SQLModel.QualifiedFieldExpression("Code", "VS")) ); var codeCondition = new Model.UnaryExpression("iExists", selectExpression); if (condition != null) { condition = new Model.BinaryExpression(condition, "iAnd", codeCondition); } else { condition = codeCondition; } } // Translate DateRange var dateRange = node.Children.Where(n => n.Name == "dateRange").FirstOrDefault(); if (dateRange != null) { var dateRangeResult = context.TranslateNode(dateRange); var dateExpression = SQLTranslationUtilities.ResolvePath(node.GetAttribute<string>("dateProperty"), "T"); // dateRangeResult will be an interval-valued expression // So the retrieve must include a where condition limiting the date range property to the interval (same as In(date, interval) translation) var dateRangeCondition = new Model.BetweenExpression(); dateRangeCondition.Expression = dateExpression; // TODO: //dateRangeCondition.LowerExpression = // dateRangeResult.Low... //dateRangeCondition.UpperExpression = // dateRangeResult.High... //if (condition != null) //{ // condition = new Model.BinaryExpression(condition, "iAnd", dateRangeCondition); //} //else //{ // condition = codeCondition; //} } // For FHIR, there will also potentially need to be profile filters... // This depends on how the FHIR model is realized within the SQL structures... var inQueryContext = ((SQLTranslationContext)context).InQueryContext(); // Within a Query Context, a retrieve is part of a FromClause var tableExpression = new SQLModel.TableExpression(requestType.Name); if (inQueryContext && (condition == null)) { return tableExpression; } else { var selectExpression = new SQLModel.SelectExpression(); selectExpression.SelectClause = new SQLModel.SelectClause(); selectExpression.SelectClause.Distinct = false; selectExpression.SelectClause.NonProject = true; selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(tableExpression, "T")); if (condition != null) { selectExpression.WhereClause = new SQLModel.WhereClause(); selectExpression.WhereClause.Expression = condition; } return selectExpression; } }
public object Translate(TranslationContext context, ASTNode node) { var result = new Model.UnaryExpression(); result.Instruction = GetOperator(); result.Expression = (Model.Expression)context.TranslateNode(node.Children[0]); return result; }
private Model.Expression TranslateRelationshipClause(TranslationContext context, Node relationship) { var relatedTableSpecifier = TranslateAliasedQuerySource(context, relationship); var relatedConditionNode = (ASTNode)relationship.Children.Where(n => n.Name == "suchThat").Single(); var relatedCondition = (Model.Expression)context.TranslateNode(relatedConditionNode); var relatedSelect = new SQLModel.SelectExpression(); relatedSelect.SelectClause = new SQLModel.SelectClause(); relatedSelect.SelectClause.NonProject = true; relatedSelect.SelectClause.Distinct = false; relatedSelect.FromClause = new SQLModel.CalculusFromClause(relatedTableSpecifier); relatedSelect.WhereClause = new SQLModel.WhereClause(relatedCondition); var relatedExists = new Model.UnaryExpression("iExists", relatedSelect); if (relationship.NodeType.GetLocalName() == "Without") { return new Model.UnaryExpression("iNot", relatedExists); } else { return relatedExists; } }