/// <summary> /// Convert the entire query to a SQL Query. /// </summary> /// <returns>The corresponding SQL Query.</returns> public SqlQuery GetSqlQuery() { SqlFromClause fromClause; if (this.inputQuery != null) { #if SUPPORT_SUBQUERIES fromClause = this.CreateSubqueryFromClause(); #else throw new DocumentQueryException("SQL subqueries currently not supported"); #endif } else { fromClause = this.CreateFrom(inputCollectionExpression: null); } // Create a SqlSelectClause with the topSpec. // If the query is flatten then selectClause may have a topSpec. It should be taken in that case. // If the query doesn't have a selectClause, use SELECT v0 where v0 is the input param. SqlSelectClause selectClause = this.selectClause; if (selectClause == null) { string parameterName = this.fromParameters.GetInputParameter().Name; SqlScalarExpression parameterExpression = SqlPropertyRefScalarExpression.Create(null, SqlIdentifier.Create(parameterName)); selectClause = this.selectClause = SqlSelectClause.Create(SqlSelectValueSpec.Create(parameterExpression)); } selectClause = SqlSelectClause.Create(selectClause.SelectSpec, selectClause.TopSpec ?? this.topSpec, selectClause.HasDistinct); SqlOffsetLimitClause offsetLimitClause = (this.offsetSpec != null) ? SqlOffsetLimitClause.Create(this.offsetSpec, this.limitSpec ?? SqlLimitSpec.Create(int.MaxValue)) : offsetLimitClause = default(SqlOffsetLimitClause); SqlQuery result = SqlQuery.Create(selectClause, fromClause, this.whereClause, this.orderByClause, offsetLimitClause); return(result); }
public override SqlObject VisitPropertyRefScalarExpressionBase([NotNull] sqlParser.PropertyRefScalarExpressionBaseContext context) { Contract.Requires(context != null); // IDENTIFIER return(SqlPropertyRefScalarExpression.Create( member: null, SqlIdentifier.Create(context.IDENTIFIER().GetText()))); }
public override bool Visit(SqlPropertyRefScalarExpression scalarExpression) { if (this.MatchesGroupByExpression(scalarExpression)) { return(true); } return(false); }
public override void Visit(SqlPropertyRefScalarExpression sqlPropertyRefScalarExpression) { if (sqlPropertyRefScalarExpression.Member != null) { sqlPropertyRefScalarExpression.Member.Accept(this); this.writer.Write("."); } sqlPropertyRefScalarExpression.Identifier.Accept(this); }
public override SqlObject VisitPropertyRefScalarExpressionRecursive([NotNull] sqlParser.PropertyRefScalarExpressionRecursiveContext context) { Contract.Requires(context != null); // primary_expression '.' IDENTIFIER SqlScalarExpression memberExpression = (SqlScalarExpression)this.Visit(context.primary_expression()); SqlIdentifier indentifier = SqlIdentifier.Create(context.IDENTIFIER().GetText()); return(SqlPropertyRefScalarExpression.Create(memberExpression, indentifier)); }
public override bool Visit(SqlPropertyRefScalarExpression sqlPropertyRefScalarExpression) { bool hasAggregates = false; if (sqlPropertyRefScalarExpression.Member != null) { hasAggregates = sqlPropertyRefScalarExpression.Member.Accept(this); } return(hasAggregates); }
public override int Visit(SqlPropertyRefScalarExpression sqlPropertyRefScalarExpression) { int hashCode = SqlPropertyRefScalarExpressionHashCode; if (sqlPropertyRefScalarExpression.Member != null) { hashCode = CombineHashes(hashCode, sqlPropertyRefScalarExpression.Member.Accept(this)); } hashCode = CombineHashes(hashCode, sqlPropertyRefScalarExpression.Identifier.Accept(this)); return(hashCode); }
public override bool Visit(SqlPropertyRefScalarExpression first, SqlObject secondAsObject) { if (!(secondAsObject is SqlPropertyRefScalarExpression second)) { return(false); } if (!Equals(first.Identifer, second.Identifer)) { return(false); } return(true); }
public override CosmosElement Visit(SqlPropertyRefScalarExpression scalarExpression, CosmosElement document) { CosmosObject documentAsObject = (CosmosObject)document; CosmosElement result; if (scalarExpression.Member == null) { // just an identifier result = documentAsObject[scalarExpression.Identifier.Value]; } else { CosmosElement member = scalarExpression.Member.Accept(this, document); CosmosElement index = CosmosString.Create(scalarExpression.Identifier.Value); result = IndexIntoMember(member, index); } return(result); }
private static SqlScalarExpression GenerateMemberIndexerScalarExpressionFromPath(Path path) { if (path.Length < 1) { throw new ArgumentException($"{nameof(path)} is too short."); } if (!(path.First() is StringPathToken rootToken)) { throw new ArgumentException($"{nameof(path)} did not start with a string."); } SqlScalarExpression rootExpression = SqlPropertyRefScalarExpression.Create( member: null, identifier: SqlIdentifier.Create(rootToken.PropertyName)); foreach (PathToken token in path.Skip(1)) { SqlLiteralScalarExpression memberIndexer; switch (token) { case StringPathToken stringPathToken: memberIndexer = SqlLiteralScalarExpression.Create( SqlStringLiteral.Create( stringPathToken.PropertyName)); break; case IntegerPathToken integerPathToken: memberIndexer = SqlLiteralScalarExpression.Create( SqlNumberLiteral.Create( integerPathToken.Index)); break; default: throw new ArgumentException($"Unknown token type: {token.GetType()}; {token}"); } rootExpression = SqlMemberIndexerScalarExpression.Create(rootExpression, memberIndexer); } return(rootExpression); }
/// <summary> /// Flatten subqueries into a single query by substituting their expressions in the current query. /// </summary> /// <returns>A flattened query.</returns> private QueryUnderConstruction Flatten() { // SELECT fo(y) FROM y IN (SELECT fi(x) FROM x WHERE gi(x)) WHERE go(y) // is translated by substituting fi(x) for y in the outer query // producing // SELECT fo(fi(x)) FROM x WHERE gi(x) AND (go(fi(x)) if (this.inputQuery == null) { // we are flat already if (this.selectClause == null) { // If selectClause doesn't exists, use SELECT v0 where v0 is the input parameter, instead of SELECT *. string parameterName = this.fromParameters.GetInputParameter().Name; SqlScalarExpression parameterExpression = SqlPropertyRefScalarExpression.Create(null, SqlIdentifier.Create(parameterName)); this.selectClause = SqlSelectClause.Create(SqlSelectValueSpec.Create(parameterExpression)); } else { this.selectClause = SqlSelectClause.Create(this.selectClause.SelectSpec, this.topSpec, this.selectClause.HasDistinct); } return(this); } QueryUnderConstruction flatInput = this.inputQuery.Flatten(); SqlSelectClause inputSelect = flatInput.selectClause; SqlWhereClause inputwhere = flatInput.whereClause; // Determine the paramName to be replaced in the current query // It should be the top input parameter name which is not binded in this collection. // That is because if it has been binded before, it has global scope and should not be replaced. string paramName = null; HashSet <string> inputQueryParams = new HashSet <string>(); foreach (Binding binding in this.inputQuery.fromParameters.GetBindings()) { inputQueryParams.Add(binding.Parameter.Name); } foreach (Binding binding in this.fromParameters.GetBindings()) { if (binding.ParameterDefinition == null || inputQueryParams.Contains(binding.Parameter.Name)) { paramName = binding.Parameter.Name; } } SqlIdentifier replacement = SqlIdentifier.Create(paramName); SqlSelectClause composedSelect = Substitute(inputSelect, inputSelect.TopSpec ?? this.topSpec, replacement, this.selectClause); SqlWhereClause composedWhere = Substitute(inputSelect.SelectSpec, replacement, this.whereClause); SqlOrderbyClause composedOrderBy = Substitute(inputSelect.SelectSpec, replacement, this.orderByClause); SqlWhereClause and = QueryUnderConstruction.CombineWithConjunction(inputwhere, composedWhere); FromParameterBindings fromParams = QueryUnderConstruction.CombineInputParameters(flatInput.fromParameters, this.fromParameters); SqlOffsetSpec offsetSpec; SqlLimitSpec limitSpec; if (flatInput.offsetSpec != null) { offsetSpec = flatInput.offsetSpec; limitSpec = flatInput.limitSpec; } else { offsetSpec = this.offsetSpec; limitSpec = this.limitSpec; } QueryUnderConstruction result = new QueryUnderConstruction(this.aliasCreatorFunc) { selectClause = composedSelect, whereClause = and, inputQuery = null, fromParameters = flatInput.fromParameters, orderByClause = composedOrderBy ?? this.inputQuery.orderByClause, offsetSpec = offsetSpec, limitSpec = limitSpec, alias = new Lazy <ParameterExpression>(() => this.Alias) }; return(result); }
public override SqlObject Visit(SqlPropertyRefScalarExpression sqlPropertyRefScalarExpression) { return(SqlPropertyRefScalarExpression.Create( sqlPropertyRefScalarExpression.Member?.Accept(this) as SqlScalarExpression, sqlPropertyRefScalarExpression.Identifier.Accept(this) as SqlIdentifier)); }
public abstract TOutput Visit(SqlPropertyRefScalarExpression sqlObject, TArg input);
public static SqlScalarExpression Substitute(SqlScalarExpression replacement, SqlIdentifier toReplace, SqlScalarExpression into) { if (into == null) { return(null); } if (replacement == null) { throw new ArgumentNullException("replacement"); } switch (into.Kind) { case SqlObjectKind.ArrayCreateScalarExpression: { SqlArrayCreateScalarExpression arrayExp = into as SqlArrayCreateScalarExpression; if (arrayExp == null) { throw new DocumentQueryException("Expected a SqlArrayCreateScalarExpression, got a " + into.GetType()); } SqlScalarExpression[] items = new SqlScalarExpression[arrayExp.Items.Count]; for (int i = 0; i < items.Length; i++) { SqlScalarExpression item = arrayExp.Items[i]; SqlScalarExpression replitem = Substitute(replacement, toReplace, item); items[i] = replitem; } return(SqlArrayCreateScalarExpression.Create(items)); } case SqlObjectKind.BinaryScalarExpression: { SqlBinaryScalarExpression binaryExp = into as SqlBinaryScalarExpression; if (binaryExp == null) { throw new DocumentQueryException("Expected a BinaryScalarExpression, got a " + into.GetType()); } SqlScalarExpression replleft = Substitute(replacement, toReplace, binaryExp.LeftExpression); SqlScalarExpression replright = Substitute(replacement, toReplace, binaryExp.RightExpression); return(SqlBinaryScalarExpression.Create(binaryExp.OperatorKind, replleft, replright)); } case SqlObjectKind.UnaryScalarExpression: { SqlUnaryScalarExpression unaryExp = into as SqlUnaryScalarExpression; if (unaryExp == null) { throw new DocumentQueryException("Expected a SqlUnaryScalarExpression, got a " + into.GetType()); } SqlScalarExpression repl = Substitute(replacement, toReplace, unaryExp.Expression); return(SqlUnaryScalarExpression.Create(unaryExp.OperatorKind, repl)); } case SqlObjectKind.LiteralScalarExpression: { return(into); } case SqlObjectKind.FunctionCallScalarExpression: { SqlFunctionCallScalarExpression funcExp = into as SqlFunctionCallScalarExpression; if (funcExp == null) { throw new DocumentQueryException("Expected a SqlFunctionCallScalarExpression, got a " + into.GetType()); } SqlScalarExpression[] items = new SqlScalarExpression[funcExp.Arguments.Count]; for (int i = 0; i < items.Length; i++) { SqlScalarExpression item = funcExp.Arguments[i]; SqlScalarExpression replitem = Substitute(replacement, toReplace, item); items[i] = replitem; } return(SqlFunctionCallScalarExpression.Create(funcExp.Name, funcExp.IsUdf, items)); } case SqlObjectKind.ObjectCreateScalarExpression: { SqlObjectCreateScalarExpression objExp = into as SqlObjectCreateScalarExpression; if (objExp == null) { throw new DocumentQueryException("Expected a SqlObjectCreateScalarExpression, got a " + into.GetType()); } return(SqlObjectCreateScalarExpression.Create( objExp .Properties .Select(prop => SqlObjectProperty.Create(prop.Name, Substitute(replacement, toReplace, prop.Expression))))); } case SqlObjectKind.MemberIndexerScalarExpression: { SqlMemberIndexerScalarExpression memberExp = into as SqlMemberIndexerScalarExpression; if (memberExp == null) { throw new DocumentQueryException("Expected a SqlMemberIndexerScalarExpression, got a " + into.GetType()); } SqlScalarExpression replMember = Substitute(replacement, toReplace, memberExp.MemberExpression); SqlScalarExpression replIndex = Substitute(replacement, toReplace, memberExp.IndexExpression); return(SqlMemberIndexerScalarExpression.Create(replMember, replIndex)); } case SqlObjectKind.PropertyRefScalarExpression: { // This is the leaf of the recursion SqlPropertyRefScalarExpression propExp = into as SqlPropertyRefScalarExpression; if (propExp == null) { throw new DocumentQueryException("Expected a SqlPropertyRefScalarExpression, got a " + into.GetType()); } if (propExp.MemberExpression == null) { if (propExp.PropertyIdentifier.Value == toReplace.Value) { return(replacement); } else { return(propExp); } } else { SqlScalarExpression replMember = Substitute(replacement, toReplace, propExp.MemberExpression); return(SqlPropertyRefScalarExpression.Create(replMember, propExp.PropertyIdentifier)); } } case SqlObjectKind.ConditionalScalarExpression: { SqlConditionalScalarExpression conditionalExpression = (SqlConditionalScalarExpression)into; if (conditionalExpression == null) { throw new ArgumentException(); } SqlScalarExpression condition = Substitute(replacement, toReplace, conditionalExpression.ConditionExpression); SqlScalarExpression first = Substitute(replacement, toReplace, conditionalExpression.FirstExpression); SqlScalarExpression second = Substitute(replacement, toReplace, conditionalExpression.SecondExpression); return(SqlConditionalScalarExpression.Create(condition, first, second)); } case SqlObjectKind.InScalarExpression: { SqlInScalarExpression inExpression = (SqlInScalarExpression)into; if (inExpression == null) { throw new ArgumentException(); } SqlScalarExpression expression = Substitute(replacement, toReplace, inExpression.Expression); SqlScalarExpression[] items = new SqlScalarExpression[inExpression.Items.Count]; for (int i = 0; i < items.Length; i++) { items[i] = Substitute(replacement, toReplace, inExpression.Items[i]); } return(SqlInScalarExpression.Create(expression, inExpression.Not, items)); } default: throw new ArgumentOutOfRangeException("Unexpected Sql Scalar expression kind " + into.Kind); } }
public abstract TResult Visit(SqlPropertyRefScalarExpression sqlObject);
public abstract void Visit(SqlPropertyRefScalarExpression scalarExpression);
public abstract void Visit(SqlPropertyRefScalarExpression sqlObject);
public static SqlScalarExpression Substitute(SqlScalarExpression replacement, SqlIdentifier toReplace, SqlScalarExpression into) { if (into == null) { return(null); } if (replacement == null) { throw new ArgumentNullException("replacement"); } switch (into) { case SqlArrayCreateScalarExpression arrayExp: { SqlScalarExpression[] items = new SqlScalarExpression[arrayExp.Items.Length]; for (int i = 0; i < items.Length; i++) { SqlScalarExpression item = arrayExp.Items[i]; SqlScalarExpression replitem = Substitute(replacement, toReplace, item); items[i] = replitem; } return(SqlArrayCreateScalarExpression.Create(items)); } case SqlBinaryScalarExpression binaryExp: { SqlScalarExpression replleft = Substitute(replacement, toReplace, binaryExp.LeftExpression); SqlScalarExpression replright = Substitute(replacement, toReplace, binaryExp.RightExpression); return(SqlBinaryScalarExpression.Create(binaryExp.OperatorKind, replleft, replright)); } case SqlUnaryScalarExpression unaryExp: { SqlScalarExpression repl = Substitute(replacement, toReplace, unaryExp.Expression); return(SqlUnaryScalarExpression.Create(unaryExp.OperatorKind, repl)); } case SqlLiteralScalarExpression literalScalarExpression: { return(into); } case SqlFunctionCallScalarExpression funcExp: { SqlScalarExpression[] items = new SqlScalarExpression[funcExp.Arguments.Length]; for (int i = 0; i < items.Length; i++) { SqlScalarExpression item = funcExp.Arguments[i]; SqlScalarExpression replitem = Substitute(replacement, toReplace, item); items[i] = replitem; } return(SqlFunctionCallScalarExpression.Create(funcExp.Name, funcExp.IsUdf, items)); } case SqlObjectCreateScalarExpression objExp: { return(SqlObjectCreateScalarExpression.Create( objExp .Properties .Select(prop => SqlObjectProperty.Create(prop.Name, Substitute(replacement, toReplace, prop.Value))) .ToImmutableArray())); } case SqlMemberIndexerScalarExpression memberExp: { SqlScalarExpression replMember = Substitute(replacement, toReplace, memberExp.Member); SqlScalarExpression replIndex = Substitute(replacement, toReplace, memberExp.Indexer); return(SqlMemberIndexerScalarExpression.Create(replMember, replIndex)); } case SqlPropertyRefScalarExpression propExp: { // This is the leaf of the recursion if (propExp.Member == null) { if (propExp.Identifier.Value == toReplace.Value) { return(replacement); } else { return(propExp); } } else { SqlScalarExpression replMember = Substitute(replacement, toReplace, propExp.Member); return(SqlPropertyRefScalarExpression.Create(replMember, propExp.Identifier)); } } case SqlConditionalScalarExpression conditionalExpression: { SqlScalarExpression condition = Substitute(replacement, toReplace, conditionalExpression.Condition); SqlScalarExpression first = Substitute(replacement, toReplace, conditionalExpression.Consequent); SqlScalarExpression second = Substitute(replacement, toReplace, conditionalExpression.Alternative); return(SqlConditionalScalarExpression.Create(condition, first, second)); } case SqlInScalarExpression inExpression: { SqlScalarExpression expression = Substitute(replacement, toReplace, inExpression.Needle); SqlScalarExpression[] items = new SqlScalarExpression[inExpression.Haystack.Length]; for (int i = 0; i < items.Length; i++) { items[i] = Substitute(replacement, toReplace, inExpression.Haystack[i]); } return(SqlInScalarExpression.Create(expression, inExpression.Not, items)); } default: throw new ArgumentOutOfRangeException("Unexpected Sql Scalar expression kind " + into.GetType()); } }