protected override object InternalVisit(SelectScalarExpression node) { return(new Func <Environment, object>(env => { return new Func <IResultTable, Selector[]>(table => { SQLExpressionInterpreter expressionInterpreter = new SQLExpressionInterpreter(Database); var expr = expressionInterpreter.Visit <Func <Environment, object> >(node.Expression); var innerEnv = env.NewChild(); var selector = new Func <IResultRow, object>((row) => { innerEnv.CurrentRow = row; return expr(innerEnv); }); //what about node.ColumnName.Identifier ?? string name = null; if (node.ColumnName != null) { name = node.ColumnName.Value; } else { //try to get the column name from the selected expression, if possible. //TODO: if i do a select (3+4) sql server says something like "(no column name)", i am guessing a result column should have a nullable name name = node.ScriptTokenStream[node.LastTokenIndex].Text; } return new Selector[] { new Selector(name, selector) }; }); })); }
internal static bool TryGetOutputColumnName(SelectScalarExpression sscalarExpr, out string columnName) { if (sscalarExpr.ColumnName != null) { if (sscalarExpr.ColumnName.ValueExpression != null) { throw new NotImplementedException(sscalarExpr.ColumnName.ValueExpression.WhatIsThis()); } else if (sscalarExpr.ColumnName.Identifier != null) { columnName = sscalarExpr.ColumnName.Identifier.Dequote(); return(true); } else { if (!string.IsNullOrEmpty(sscalarExpr.ColumnName.Value)) { columnName = sscalarExpr.ColumnName.Value; return(true); } columnName = null; return(false); } } else { columnName = null; return(false); } }
public override void VisitSelectScalarExpression(SelectScalarExpression selectScalarExpression) { selectScalarExpression.Expression.Accept(this); var expression = expressionStack.Pop(); string columnName = selectScalarExpression.Alias ?? nameStack.Pop(); selectExpressions.Add(new SelectExpression(expression, columnName)); }
public override void Visit(SelectScalarExpression node) { var columnName = node.ColumnName is null ? string.Empty : node.ColumnName.Value; var isLiteral = node.Expression is Literal; ReturnValues.Add(new SelectElementWrapper(node, _queryExpressionId, columnName, isLiteral)); base.Visit(node); }
public void TestSelectScalarExpressionAccept() { Mock <KoraliumSqlVisitor> mock = new Mock <KoraliumSqlVisitor>(); SelectScalarExpression selectScalarExpression = new SelectScalarExpression(); selectScalarExpression.Accept(mock.Object); mock.Verify(x => x.VisitSelectScalarExpression(selectScalarExpression)); }
public override void ExplicitVisit(SelectScalarExpression node) { base.ExplicitVisit(node); // Keep track of aliases introduced in the SELECT clause so we can ignore them later if (!String.IsNullOrEmpty(node.ColumnName?.Identifier?.Value)) { _selectAliases.Add(node.ColumnName.Identifier.Value); } }
public QsiColumnNode VisitSelectScalarExpression(SelectScalarExpression selectScalarExpression) { QsiExpressionNode expression = null; QsiColumnReferenceNode column = null; if (selectScalarExpression.Expression is ColumnReferenceExpression columnReferenceExpression) { column = new QsiColumnReferenceNode { Name = IdentifierVisitor.CreateQualifiedIdentifier(columnReferenceExpression.MultiPartIdentifier) }; if (selectScalarExpression.ColumnName == null) { SqlServerTree.PutFragmentSpan(column, selectScalarExpression); return(column); } } else { expression = ExpressionVisitor.VisitScalarExpression(selectScalarExpression.Expression); } return(TreeHelper.Create <QsiDerivedColumnNode>(n => { if (column != null) { n.Column.SetValue(column); } else if (expression != null) { n.Expression.SetValue(expression); } var columnName = selectScalarExpression.ColumnName; if (columnName != null) { if (columnName.Identifier == null) { n.Alias.SetValue(new QsiAliasNode { Name = new QsiIdentifier(columnName.Value, false) }); } else { n.Alias.SetValue(CreateAliasNode(columnName.Identifier)); } } SqlServerTree.PutFragmentSpan(n, selectScalarExpression); })); }
public override void Visit(SelectScalarExpression node) { base.Visit(node); var identifier = new IdentifierVisitor(); node.Accept(identifier); this.SelectNodes.Add( String.Join(".", identifier.SelectNodes.Select(x => x.Value) )); }
public void TestVisitSelectScalarExpression() { Mock <ScalarExpression> mock = new Mock <ScalarExpression>(); SelectScalarExpression selectScalarExpression = new SelectScalarExpression() { Expression = mock.Object }; KoraliumSqlVisitor koraliumSqlVisitor = new KoraliumSqlVisitor(); koraliumSqlVisitor.Visit(selectScalarExpression); mock.Verify(x => x.Accept(koraliumSqlVisitor)); }
public void TestSelectScalarExpressionEquals() { SelectScalarExpression first = new SelectScalarExpression() { Alias = "test", Expression = new StringLiteral() { Value = "t" } }; SelectScalarExpression firstClone = new SelectScalarExpression() { Alias = "test", Expression = new StringLiteral() { Value = "t" } }; SelectScalarExpression second = new SelectScalarExpression() { Alias = "test2", Expression = new StringLiteral() { Value = "t" } }; SelectScalarExpression third = new SelectScalarExpression() { Alias = "test", Expression = new StringLiteral() { Value = "t2" } }; //Equals Assert.IsTrue(Equals(first, firstClone)); Assert.IsFalse(Equals(first, null)); Assert.IsFalse(Equals(first, second)); Assert.IsFalse(Equals(first, third)); Assert.IsFalse(Equals(first, "other type")); //Hash code Assert.AreEqual(first.GetHashCode(), firstClone.GetHashCode()); Assert.AreNotEqual(first.GetHashCode(), second.GetHashCode()); Assert.AreNotEqual(first.GetHashCode(), third.GetHashCode()); }
public void TestCloneSelectScalarExpression() { SelectScalarExpression selectScalarExpression = new SelectScalarExpression() { Alias = "test", Expression = new StringLiteral() { Value = "t" } }; var clone = selectScalarExpression.Clone() as SelectScalarExpression; Assert.AreEqual(selectScalarExpression, clone); Assert.IsFalse(ReferenceEquals(selectScalarExpression, clone)); Assert.IsFalse(ReferenceEquals(selectScalarExpression.Expression, clone.Expression)); }
public override void ExplicitVisit(SelectScalarExpression node) { // IIF(@limitreached = 1, 1, 0) if (hasSetVariable) { outputSet.Clear(); } else { //Console.WriteLine("Resolve type for scalar:" + node.AsText()); OutputColumnDescriptor columnDbType = resolveColumnType ? columnTypeResolver.ResolveSelectScalarExpression(node) : null; if (columnDbType == null || columnDbType.ColumnType == null) { // put a breakpoint here //this column cannot be resolved from this query. if this is a part of a IF statemt try ELSE branch. } outputSet.AddColumn(new ProcedureOutputColumn(node, columnDbType)); // SelectScalarExpression } }
public override void ExplicitVisit(SelectScalarExpression node) { base.ExplicitVisit(node); var originalColumn = node.Expression as ColumnReferenceExpression; var name = ReplaceExpression(node, n => n.Expression); if (name != null && node.ColumnName == null) { var alias = name; if (originalColumn != null) { alias = originalColumn.MultiPartIdentifier.Identifiers.Last().Value; } node.ColumnName = new IdentifierOrValueExpression { Identifier = new Identifier { Value = alias } }; } }
/// <summary> /// Initializes a new instance of the <see cref="SelectColumn" /> class. /// </summary> /// <param name="selectScalarExpression">The select scalar expression.</param> /// <param name="bodyColumnTypes">The body column types.</param> /// <param name="tableAliases">The table aliases.</param> /// <param name="outerJoinedTables">The aliases or names of tables that were outer joined. Used to determine if a non-nulllable column could still be null.</param> /// <exception cref="System.InvalidOperationException">Could not find column within BodyDependencies: + fullColName</exception> public SelectColumn(SelectScalarExpression selectScalarExpression, IDictionary <string, DataType> bodyColumnTypes, IDictionary <string, string> tableAliases, IEnumerable <string> outerJoinedTables) { if (selectScalarExpression.Expression is ColumnReferenceExpression) { var columnReferenceExpression = (ColumnReferenceExpression)selectScalarExpression.Expression; var identifiers = columnReferenceExpression.MultiPartIdentifier.Identifiers; var fullColName = this.GetFullColumnName(tableAliases, identifiers); this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : identifiers.Last().Value; var key = bodyColumnTypes.Keys.FirstOrDefault(x => x.EndsWith(fullColName, StringComparison.InvariantCultureIgnoreCase)); if (key == null) { throw new InvalidOperationException("Could not find column within BodyDependencies: " + fullColName); } bool outerJoined = false; // If the column was defined in the SELECT with the table alias or name, check if the table was outer joined. if (identifiers.Count() > 1) { var tableAliasOrName = identifiers.ElementAt(identifiers.Count() - 2).Value; outerJoined = outerJoinedTables.Contains(tableAliasOrName); } else // If the column was defined in the SELECT without any qualification, then there must // be only one column in the list of tables with that name. Look it up in the bodyColumnTypes. { var keyParts = key.Split('.'); if (keyParts.Count() > 1) { var tableAliasOrName = keyParts.ElementAt(keyParts.Count() - 2); outerJoined = outerJoinedTables.Contains(tableAliasOrName); } } var bodyColumnType = bodyColumnTypes[key]; this.DataTypes = bodyColumnType.Map; this.IsNullable = bodyColumnType.Nullable || outerJoined; } else if (selectScalarExpression.Expression is ConvertCall) { var convertCall = (ConvertCall)selectScalarExpression.Expression; this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : "Value"; this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.SqlServerDbType, convertCall.DataType.Name.BaseIdentifier.Value); this.IsNullable = true; } else if (selectScalarExpression.Expression is CastCall) { var castCall = (CastCall)selectScalarExpression.Expression; this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : "Value"; this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.SqlServerDbType, castCall.DataType.Name.BaseIdentifier.Value); this.IsNullable = true; } else if (selectScalarExpression.Expression is IntegerLiteral) { var integerLiteral = (IntegerLiteral)selectScalarExpression.Expression; this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : "Value"; this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.SqlServerDbType, "int"); this.IsNullable = true; } else if (selectScalarExpression.Expression is VariableReference) { var variableReference = (VariableReference)selectScalarExpression.Expression; this.Name = variableReference.Name.TrimStart('@'); this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.DotNetFrameworkType, "Object"); this.IsNullable = true; } else { this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : "Value"; this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.DotNetFrameworkType, "Object"); this.IsNullable = true; } }
public virtual void VisitSelectScalarExpression(SelectScalarExpression selectScalarExpression) { Visit(selectScalarExpression.Expression); //DONE }
/// <summary> /// Initializes a new instance of the <see cref="SelectColumn" /> class. /// </summary> /// <param name="selectScalarExpression">The select scalar expression.</param> /// <param name="bodyColumnTypes">The body column types.</param> /// <param name="tableAliases">The table aliases.</param> /// <param name="outerJoinedTables">The aliases or names of tables that were outer joined. Used to determine if a non-nulllable column could still be null.</param> /// <exception cref="System.InvalidOperationException">Could not find column within BodyDependencies: + fullColName</exception> public SelectColumn(SelectScalarExpression selectScalarExpression, IDictionary<string, DataType> bodyColumnTypes, IDictionary<string, string> tableAliases, IEnumerable<string> outerJoinedTables) { if (selectScalarExpression.Expression is ColumnReferenceExpression) { var columnReferenceExpression = (ColumnReferenceExpression)selectScalarExpression.Expression; var identifiers = columnReferenceExpression.MultiPartIdentifier.Identifiers; var fullColName = this.GetFullColumnName(tableAliases, identifiers); this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : identifiers.Last().Value; var key = bodyColumnTypes.Keys.FirstOrDefault(x => x.EndsWith(fullColName, StringComparison.InvariantCultureIgnoreCase)); if (key == null) throw new InvalidOperationException("Could not find column within BodyDependencies: " + fullColName); bool outerJoined = false; // If the column was defined in the SELECT with the table alias or name, check if the table was outer joined. if (identifiers.Count() > 1) { var tableAliasOrName = identifiers.ElementAt(identifiers.Count() - 2).Value; outerJoined = outerJoinedTables.Contains(tableAliasOrName); } else // If the column was defined in the SELECT without any qualification, then there must // be only one column in the list of tables with that name. Look it up in the bodyColumnTypes. { var keyParts = key.Split('.'); if (keyParts.Count() > 1) { var tableAliasOrName = keyParts.ElementAt(keyParts.Count() - 2); outerJoined = outerJoinedTables.Contains(tableAliasOrName); } } var bodyColumnType = bodyColumnTypes[key]; this.DataTypes = bodyColumnType.Map; this.IsNullable = bodyColumnType.Nullable || outerJoined; } else if (selectScalarExpression.Expression is ConvertCall) { var convertCall = (ConvertCall)selectScalarExpression.Expression; this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : "Value"; this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.SqlServerDbType, convertCall.DataType.Name.BaseIdentifier.Value); this.IsNullable = true; } else if (selectScalarExpression.Expression is CastCall) { var castCall = (CastCall)selectScalarExpression.Expression; this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : "Value"; this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.SqlServerDbType, castCall.DataType.Name.BaseIdentifier.Value); this.IsNullable = true; } else if (selectScalarExpression.Expression is IntegerLiteral) { var integerLiteral = (IntegerLiteral)selectScalarExpression.Expression; this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : "Value"; this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.SqlServerDbType, "int"); this.IsNullable = true; } else if (selectScalarExpression.Expression is VariableReference) { var variableReference = (VariableReference)selectScalarExpression.Expression; this.Name = variableReference.Name.TrimStart('@'); this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.DotNetFrameworkType, "Object"); this.IsNullable = true; } else { this.Name = selectScalarExpression.ColumnName != null && selectScalarExpression.ColumnName.Value != null ? selectScalarExpression.ColumnName.Value : "Value"; this.DataTypes = DataTypeHelper.Instance.GetMap(TypeFormat.DotNetFrameworkType, "Object"); this.IsNullable = true; } }
public override void Visit(SelectScalarExpression node) { this.action(node); }
public override void ExplicitVisit(SelectScalarExpression fragment) { _fragments.Add(fragment); }
public gsColumnParserSelectScalar(SelectElement element) : base(element) { _Expression = element as SelectScalarExpression; }
public override void VisitSelectScalarExpression(SelectScalarExpression selectScalarExpression) { selectScalarExpression.Expression.Accept(this); ColumnName = selectScalarExpression.Alias ?? nameStack.Pop(); }
public override void ExplicitVisit(SelectScalarExpression node) { base.ExplicitVisit(node); }
public OutputColumnDescriptor ResolveSelectScalarExpression(SelectScalarExpression node) { IQueryModel model = EnsureModel(); if (TryGetOutputColumnName(node, out string outputColumnName)) { if (model.TryGetQueryOutputColumnByName(batchResolver, outputColumnName, out QueryColumnBase col)) { return(ColumnModelToDescriptor(col)); } throw new NotImplementedException(node.Expression.WhatIsThis()); } else if (node.Expression is ColumnReferenceExpression colRef) { if (TryColumnReference(model, colRef, out QueryColumnBase col)) { return(ColumnModelToDescriptor(col)); } throw new NotImplementedException(node.Expression.WhatIsThis()); } else if (node.Expression is IIfCall iif) { // no output name! if single column output -> use it??? if (TrtGetAnonymousColumnType_ScalarExpression(iif.ThenExpression, out DbType columnDbTypeT, out bool allowNull)) { return(ColumnModelToDescriptor(columnDbTypeT, allowNull)); } if (TrtGetAnonymousColumnType_ScalarExpression(iif.ThenExpression, out DbType columnDbTypeE, out allowNull)) { return(ColumnModelToDescriptor(columnDbTypeE, allowNull)); } throw new NotImplementedException(iif.ElseExpression.WhatIsThis()); } else if (node.Expression is CastCall castExpr) { var dbType = ProcedureGenerator.ResolveToDbDataType(castExpr.DataType); return(ColumnModelToDescriptor(dbType, true)); } else if (node.Expression is VariableReference varRefExpr) { var varType = batchResolver.TryGetScalarVariableType(varRefExpr.Name); if (varType != null) { return(ColumnModelToDescriptor(varType.ColumnDbType, varType.AllowNull)); } throw new NotImplementedException(varRefExpr.Name); } else if (node.Expression is FunctionCall fCall) { string functionName = fCall.FunctionName.Dequote(); if (string.Equals(functionName, "COUNT", StringComparison.OrdinalIgnoreCase)) { return(ColumnModelToDescriptor(DbType.Int32, true)); } throw new NotImplementedException(fCall.WhatIsThis()); } else { throw new NotImplementedException(node.Expression.WhatIsThis()); } }
private void ProcessViewStatementBody(TSqlStatement sqlStatement) { ViewStatementBody aViewStatementBody = (ViewStatementBody)sqlStatement; AddLogText("Columns:"); foreach (Identifier aColumnIdentifier in aViewStatementBody.Columns) { AddLogText(string.Format("Column:{0}", aColumnIdentifier.Value)); aColumnInfoList.ColumnList.Add(new ColumnInfo { Alias = aColumnIdentifier.Value }); } AddLogText(""); AddLogText("QueryExpression SelectElements:"); SelectStatement aSelectStatement = aViewStatementBody.SelectStatement; QueryExpression aQueryExpression = aSelectStatement.QueryExpression; if (aQueryExpression.GetType() == typeof(QuerySpecification)) { QuerySpecification aQuerySpecification = (QuerySpecification)aQueryExpression; int aSelectElementID = 0; foreach (SelectElement aSelectElement in aQuerySpecification.SelectElements) { if (aSelectElement.GetType() == typeof(SelectScalarExpression)) { SelectScalarExpression aSelectScalarExpression = (SelectScalarExpression)aSelectElement; string identStr = string.Empty; IdentifierOrValueExpression aIdentifierOrValueExpression = aSelectScalarExpression.ColumnName; if (aIdentifierOrValueExpression != null) { if (aIdentifierOrValueExpression.ValueExpression == null) { AddLogText(string.Format("Identifier={0}", aIdentifierOrValueExpression.Identifier.Value)); identStr = aIdentifierOrValueExpression.Identifier.Value; } else { AddLogText("Expression"); } } aColumnInfoList.AddIfNeeded(aSelectElementID, identStr); ScalarExpression aScalarExpression = aSelectScalarExpression.Expression; PrintSelectScalarExperssionRecurse(aSelectElementID, aScalarExpression); } else { aColumnInfoList.AddIfNeeded(aSelectElementID, "Error, something else than SelectScalarExpression found"); AddLogText("We only support SelectScalarExpression."); } aSelectElementID = aSelectElementID + 1; AddLogText(""); } AddLogText(""); AddLogText("Table References:"); FromClause aFromClause = aQuerySpecification.FromClause; foreach (TableReference aTableReference in aFromClause.TableReferences) { PrintTableReferenceRecurse(aTableReference); } } aColumnInfoList.FillEmptyAlias(); }//function
/// <summary> /// Adds attributes to the SELECT clause /// </summary> /// <param name="query">The SQL query to append to the SELECT clause of</param> /// <param name="items">The FetchXML items to process</param> /// <param name="prefix">The name or alias of the table being processed</param> private static void AddSelectElements(QuerySpecification query, object[] items, string prefix) { if (items == null) { return; } // Handle <all-attributes /> as SELECT table.* foreach (var all in items.OfType <allattributes>()) { query.SelectElements.Add(new SelectStarExpression { Qualifier = new MultiPartIdentifier { Identifiers = { new Identifier { Value = prefix } } } }); } // Handle attributes with each combination of aliases, aggregates, distincts, groupings // <attribute name="attr" alias="a" aggregate="count" distinct="true" /> // <attribute name="attr" alias="a" groupby="true" dategrouping="month" /> foreach (var attr in items.OfType <FetchAttributeType>()) { var element = new SelectScalarExpression(); // Core column reference var col = new ColumnReferenceExpression { MultiPartIdentifier = new MultiPartIdentifier { Identifiers = { new Identifier { Value = prefix }, new Identifier { Value = attr.name } } } }; // Apply aggregates or date grouping as function calls if (attr.aggregateSpecified) { var func = new FunctionCall { FunctionName = new Identifier { Value = attr.aggregate == AggregateType.countcolumn ? "count" : attr.aggregate.ToString() }, Parameters = { col } }; if (attr.distinctSpecified && attr.distinct == FetchBoolType.@true) { func.UniqueRowFilter = UniqueRowFilter.Distinct; } element.Expression = func; } else if (attr.dategroupingSpecified) { var func = new FunctionCall { FunctionName = new Identifier { Value = "DATEPART" }, Parameters = { new ColumnReferenceExpression { MultiPartIdentifier = new MultiPartIdentifier { Identifiers = { new Identifier { Value = attr.dategrouping.ToString() } } } }, col } }; element.Expression = func; } else { element.Expression = col; } // Apply alias if (!String.IsNullOrEmpty(attr.alias) && (attr.aggregateSpecified || attr.alias != attr.name)) { element.ColumnName = new IdentifierOrValueExpression { Identifier = new Identifier { Value = attr.alias } } } ; query.SelectElements.Add(element); // Apply grouping if (attr.groupbySpecified && attr.groupby == FetchBoolType.@true) { if (query.GroupByClause == null) { query.GroupByClause = new GroupByClause(); } if (attr.dategroupingSpecified) { query.GroupByClause.GroupingSpecifications.Add(new ExpressionGroupingSpecification { Expression = new FunctionCall { FunctionName = new Identifier { Value = "DATEPART" }, Parameters = { new ColumnReferenceExpression { MultiPartIdentifier = new MultiPartIdentifier { Identifiers = { new Identifier { Value = attr.dategrouping.ToString() } } } }, col } } }); } else { query.GroupByClause.GroupingSpecifications.Add(new ExpressionGroupingSpecification { Expression = col }); } } } }