Пример #1
0
		public object Translate(TranslationContext context, ASTNode node)
		{
			var result = new SQLModel.TableExpression();
			var sqlContext = (SQLTranslationContext)context;
			result.TableName = sqlContext.GetExpressionObjectName(String.Format("{0}.{1}", node.GetAttribute<string>("libraryName", sqlContext.ArtifactName), node.GetAttribute<string>("name")));

			// If the expression being referenced is scalar, it will be automatically promoted to a query by the expression def translation
			// In this case, it must be demoted back to a scalar expression with a subquery access.
			if (!(node.ResultType is ListType) && !(node.ResultType is ObjectType))
			{
				var selectExpression = new SQLModel.SelectExpression();
				selectExpression.SelectClause = new SQLModel.SelectClause();
				selectExpression.SelectClause.Columns.Add(new SQLModel.ColumnExpression(new SQLModel.QualifiedFieldExpression("value")));
				selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(result));

				// If the result type is also boolean, the expression will be converted to a 1 or 0, so it must be demoted back to an actual boolean-valued expression
				if (DataTypes.Equal(node.ResultType, DataTypes.Boolean))
				{
					return SQLTranslationUtilities.DemoteBooleanValuedExpression(selectExpression);
				}

				return selectExpression;
			}

			return result;
		}
Пример #2
0
 protected override void EmitSelectExpression(SQL.SelectExpression expression)
 {
     AppendFormat("{0} /*+ {1}*/ ", SQL.Keywords.Select, expression is SelectExpression ? ((SelectExpression)expression).OptimizerHints : "FIRST_ROWS(20)");
     IncreaseIndent();
     EmitSelectClause(expression.SelectClause);
     EmitFromClause(expression.FromClause);
     EmitWhereClause(expression.WhereClause);
     EmitGroupClause(expression.GroupClause);
     EmitHavingClause(expression.HavingClause);
     DecreaseIndent();
 }
        /// <summary>
        /// Ensures that the given expression, if not a select expression, is promoted to a select expression.
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static Model.Expression EnsureSelectExpression(object expression)
        {
            if (!(expression is SQLModel.SelectExpression) && !(expression is SQLModel.QueryExpression) && !(expression is SQLModel.SelectStatement) && !(expression is SQLModel.SelectStatementExpression))
            {
                var selectExpression = new SQLModel.SelectExpression();
                selectExpression.SelectClause = new SQLModel.SelectClause();
                selectExpression.SelectClause.Columns.Add(new SQLModel.ColumnExpression((Model.Expression)expression, "value"));
                return(selectExpression);
            }

            return(EnsureSelectStatementExpression(expression));
        }
		/// <summary>
		/// Ensures that the given expression, if not a select expression, is promoted to a select expression.
		/// </summary>
		/// <param name="expression"></param>
		/// <returns></returns>
		public static Model.Expression EnsureSelectExpression(object expression)
		{
			if (!(expression is SQLModel.SelectExpression) && !(expression is SQLModel.QueryExpression) && !(expression is SQLModel.SelectStatement) && !(expression is SQLModel.SelectStatementExpression))
			{
				var selectExpression = new SQLModel.SelectExpression();
				selectExpression.SelectClause = new SQLModel.SelectClause();
				selectExpression.SelectClause.Columns.Add(new SQLModel.ColumnExpression((Model.Expression)expression, "value"));
				return selectExpression;
			}

			return EnsureSelectStatementExpression(expression);
		}
Пример #5
0
        protected override void EmitSelectExpression(SQL.SelectExpression expression)
        {
            AppendFormat("{0} ", Alphora.Dataphor.DAE.Language.SQL.Keywords.Select);
            IncreaseIndent();
            EmitSelectClause(expression.SelectClause);
            EmitFromClause(expression.FromClause);
            EmitWhereClause(expression.WhereClause);
            EmitGroupClause(expression.GroupClause);
            EmitHavingClause(expression.HavingClause);

            // Add the "for" clause
            var pgSelect = expression as SelectExpression;

            if (pgSelect != null)
            {
                EmitForClause(pgSelect.ForSpecifier);
            }

            DecreaseIndent();
        }
Пример #6
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // In(element, interval)...
            // In(element, list)
            // Translate as:
            // exists (select * from (<list>) T where <element equality condition>)

            // As long as this is list containment, it can be translated using an Exists(Filter(Collection, Condition(Current = Element)));
            var elementNode = node.Children[0];
            var collectionNode = node.Children[1];

            if (elementNode.ResultType is ListType)
            {
                throw new NotSupportedException("In translation with an element of type list is not supported because there is no equivalent SQL representation.");
            }

            if (collectionNode.ResultType is ListType)
            {
                var selectExpression = new SQLModel.SelectExpression();
                selectExpression.SelectClause = new SQLModel.SelectClause();
                selectExpression.SelectClause.NonProject = true;
                selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(SQLTranslationUtilities.EnsureSelectStatementExpression(context.TranslateNode(collectionNode)), "T"));
                selectExpression.WhereClause = new SQLModel.WhereClause();

                Model.Expression condition = null;
                if (elementNode.ResultType is ObjectType)
                {
                    foreach (var property in ((ObjectType)elementNode.ResultType).Properties)
                    {
                        // TODO: O is an assumed alias here, need a way to establish the outer context for comparison of the element....
                        var propertyCondition = new Model.BinaryExpression(new SQLModel.QualifiedFieldExpression(property.Name, "T"), "iEqual", new SQLModel.QualifiedFieldExpression(property.Name, "O"));

                        if (condition == null)
                        {
                            condition = propertyCondition;
                        }
                        else
                        {
                            condition = new Model.BinaryExpression(condition, "iAnd", propertyCondition);
                        }
                    }
                }
                else
                {
                    condition = new Model.BinaryExpression(new SQLModel.QualifiedFieldExpression("value", "T"), "iEqual", (Model.Expression)context.TranslateNode(elementNode));
                }

                selectExpression.WhereClause.Expression = condition;
                return selectExpression;
            }
            else
            {
                var betweenExpression = new Model.BetweenExpression();
                betweenExpression.Expression = (Model.Expression)context.TranslateNode(elementNode);
                // TODO: Translate an interval selector....
                betweenExpression.LowerExpression = new Model.ValueExpression(1);
                betweenExpression.UpperExpression = new Model.ValueExpression(1);
                return betweenExpression;
            }
        }
Пример #7
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var selectExpression = new SQLModel.SelectExpression();
            selectExpression.SelectClause = new SQLModel.SelectClause();
            selectExpression.SelectClause.NonProject = true;
            selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(new SQLModel.TableExpression("ValueSet"), "VS"));
            selectExpression.WhereClause = new SQLModel.WhereClause();

            var valueSetName = node.GetAttribute<String>("name");
            var valueSetLibraryName = node.GetAttribute<String>("libraryName", ((SQLTranslationContext)context).ArtifactName);
            var valueSetCondition =
                new Model.BinaryExpression
                (
                    new SQLModel.QualifiedFieldExpression("ValueSetName", "VS"),
                    "iEqual",
                    new Model.ValueExpression(String.Format("{0}.{1}", valueSetLibraryName, valueSetName), Model.TokenType.String)
                );

            selectExpression.WhereClause.Expression = valueSetCondition;

            return selectExpression;
        }
Пример #8
0
        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;
            }
        }
Пример #9
0
 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;
     }
 }
Пример #10
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var selectExpression = new SQLModel.SelectExpression();

            var fromClause = new SQLModel.CalculusFromClause();
            selectExpression.FromClause = fromClause;

            var queryExpression = new SQLModel.QueryExpression();
            queryExpression.SelectExpression = selectExpression;

            var selectStatement = new SQLModel.SelectStatement();
            selectStatement.QueryExpression = queryExpression;

            // 1..* source: AliasedQuerySource
            foreach (var child in ((Node)node).Children.Where(n => n.Name == "source"))
            {
                var tableSpecifier = TranslateAliasedQuerySource(context, child);
                fromClause.TableSpecifiers.Add(tableSpecifier);
            }

            // 0..* define: DefineClause
            foreach (var child in ((Node)node).Children.Where(n => n.Name == "define"))
            {
                // TODO: This would need to be nested to be accessible within context in the SQL query
                throw new NotImplementedException("Define clause translation is not yet implemented");
            }

            // 0..* relationship: With | Without
            Model.Expression relationshipConditions = null;
            foreach (var child in ((Node)node).Children.Where(n => n.Name == "relationship"))
            {
                var relationshipCondition = TranslateRelationshipClause(context, child);
                if (relationshipConditions != null)
                {
                    relationshipConditions = new Model.BinaryExpression(relationshipConditions, "iAnd", relationshipCondition);
                }
                else
                {
                    relationshipConditions = relationshipCondition;
                }
            }

            // 0..1 where: Expression
            Model.Expression whereCondition = null;
            var whereConditionNode = node.Children.SingleOrDefault(n => n.Name == "where");
            if (whereConditionNode != null)
            {
                whereCondition = (Model.Expression)context.TranslateNode(whereConditionNode);
            }

            // 0..1 return: ReturnClause
            var returnClause = ((Node)node).Children.SingleOrDefault(n => n.Name == "return");
            if (returnClause != null)
            {
                var selectClause = TranslateReturnClause(context, returnClause);
                selectExpression.SelectClause = selectClause;
            }

            if (selectExpression.SelectClause == null)
            {
                selectExpression.SelectClause = new SQLModel.SelectClause();
                selectExpression.SelectClause.NonProject = true;
            }

            // 0..1 sort: SortClause
            var sortClause = ((Node)node).Children.SingleOrDefault(n => n.Name == "sort");
            if (sortClause != null)
            {
                var orderClause = TranslateSortClause(context, sortClause);
                selectStatement.OrderClause = orderClause;
            }

            return selectStatement;
        }
Пример #11
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // If the property has a source
                // select propertyName as value from (<source>)
            // Else
                // If the property has a scope
                    // It's a qualified field expression
                // Else
                    // It's an identifier expression

            // TODO: Handle nested and indexed paths...
            var path = node.GetAttribute<string>("path");
            var source = node.Children.Where(c => c.Name == "source").FirstOrDefault();
            if (source != null)
            {
                var selectExpression = new SQLModel.SelectExpression();
                selectExpression.SelectClause = new SQLModel.SelectClause();
                selectExpression.SelectClause.Columns.Add(new SQLModel.ColumnExpression(SQLTranslationUtilities.ResolvePath(path, "T"), "value"));
                selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(SQLTranslationUtilities.EnsureExpression(context.TranslateNode(source)), "T"));
                return selectExpression;
            }
            else
            {
                var scope = node.GetAttribute<string>("scope", VerificationContext.Current);
                if (scope != VerificationContext.Current)
                {
                    return SQLTranslationUtilities.ResolvePath(path, "T");
                }
                else
                {
                    return SQLTranslationUtilities.ResolvePath(path, null);
                }
            }

            //var sourceType = node.GetAttribute<ObjectType>("sourceType");

            // Translate path information
            //return context.TransformModelPath(sourceType, node, node.GetAttribute<string>("path"));
        }