/// <summary>
        /// A SELECT statement containing an INTO clause is not a data query but a data manipulation
        /// This method pushes such a SELECT statement to the related list
        /// </summary>
        internal void AddSelectWithIntoClause(SelectStatement statement)
        {
            var manipulation = new DataManipulation();

            foreach (var expr in statement.Expression.ChildExpressions)
            {
                if (expr.Type.Equals(ExpressionType.COLUMN))
                {
                    var singleManipulation = new Expression(ExpressionType.COLUMN)
                    {
                        Name = Beautifier.EnhanceNotation(statement.TargetObject, InternalConstants.UNRELATED_COLUMN_NAME)
                    };

                    singleManipulation.ChildExpressions.Add(expr);
                    manipulation.Expressions.Add(singleManipulation);
                }
            }

            DataManipulations.Add(manipulation);
        }
        /// <summary>
        /// Loops through all collected database objects and add a
        /// whole-object-synonymous for each object that is not referenced
        /// in a column
        /// </summary>
        private void AddSynonymousObjects(List <DatabaseObject> databaseObjects)
        {
            foreach (var dbo in databaseObjects)
            {
                if (!dbo.Type.Equals(DatabaseObjectType.REAL))
                {
                    continue;
                }

                bool isReferenced = false;

                foreach (var expr in statement.Expression.ChildExpressions)
                {
                    if (!expr.Type.Equals(ExpressionType.COLUMN))
                    {
                        continue;
                    }

                    Helper.SplitColumnNotationIntoSingleParts(expr.Name, out string databaseName, out string schemaName, out string dboName, out string columnName);

                    if (dbo.Name.Equals(dboName))
                    {
                        isReferenced = true;
                        break;
                    }
                }

                if (!isReferenced)
                {
                    var sourceSynonymous = new Expression(ExpressionType.COLUMN)
                    {
                        Name = Beautifier.EnhanceNotation(dbo, InternalConstants.WHOLE_OBJECT_SYNONYMOUS),
                        WholeObjectSynonymous = true
                    };
                    statement.Expression.ChildExpressions.Add(sourceSynonymous);
                }
            }
        }
        public DataManipulation Resolve(ReadOnlySpan <TSQLToken> tokens, ref int fileIndex, CompilerContext context)
        {
            manipulation = new DataManipulation();

            fileIndex++; //skip 'update'

            var targetObject = StatementResolveHelper.ResolveDatabaseObject(tokens, ref fileIndex, context, true);

            fileIndex++; //skip 'set'

            do
            {
                //Resolves the target object. Note that this target can be an alias that is resolved later in the FROM statement
                var target = StatementResolveHelper.ResolveExpression(tokens, ref fileIndex, context);

                AddTargetObject(target, targetObject);

                fileIndex++;                                                                           //skip '='

                var source = StatementResolveHelper.ResolveExpression(tokens, ref fileIndex, context); //resolve source column
                target.ChildExpressions.Add(source);

                manipulation.Expressions.Add(target);

                if (fileIndex < tokens.Length && tokens[fileIndex].Text.Equals(","))
                {
                    fileIndex++; //skip ','
                    continue;
                }
                else
                {
                    break;
                }
            } while (true);

            var objects = StatementResolveHelper.ResolveFromStatement(tokens, ref fileIndex, context);

            AddObjectsToContext(objects, context);

            if (objects.Count > 1)
            {
                targetObject = AssignRealTarget(objects, targetObject);
                var targetSynonymous = new Expression(ExpressionType.COLUMN)
                {
                    Name = Beautifier.EnhanceNotation(targetObject, InternalConstants.WHOLE_OBJECT_SYNONYMOUS),
                    WholeObjectSynonymous = true
                };

                foreach (var dbo in objects)
                {
                    if (!dbo.Type.Equals(DatabaseObjectType.REAL) || dbo.Equals(targetObject))
                    {
                        continue;
                    }
                    var sourceSynonymous = new Expression(ExpressionType.COLUMN)
                    {
                        Name = Beautifier.EnhanceNotation(dbo, InternalConstants.WHOLE_OBJECT_SYNONYMOUS),
                        WholeObjectSynonymous = true
                    };
                    targetSynonymous.ChildExpressions.Add(sourceSynonymous);
                    manipulation.Expressions.Add(targetSynonymous);
                }
            }

            var beautified = new List <Expression>();

            foreach (var expr in manipulation.Expressions)
            {
                beautified.Add(Beautifier.BeautifyColumns(expr, context));
            }

            manipulation.Expressions = beautified;

            StatementResolveHelper.ResolveWhereStatement(tokens, ref fileIndex, context);

            PopObjectsFromContextStack(context);

            return(manipulation);
        }
Beispiel #4
0
        public DataManipulation Resolve(ReadOnlySpan <TSQLToken> tokens, ref int fileIndex, CompilerContext context)
        {
            manipulation = new DataManipulation();

            fileIndex++; //skip 'insert'

            //TODO Resolve TOP Expression

            if (tokens[fileIndex].Text.ToLower().Equals("into"))
            {
                fileIndex++; //skip 'into'
            }
            targetObject = StatementResolveHelper.ResolveDatabaseObject(tokens, ref fileIndex, context, true);

            DetermineTargetColumns(tokens, ref fileIndex, context);

            //TODO Resolve Table Hint

            if (tokens[fileIndex].Text.Equals("values", StringComparison.InvariantCultureIgnoreCase))
            {
                fileIndex += 2; //skip 'values ('
                DetermineSourceObjects(tokens, ref fileIndex, context);
            }
            else if (tokens[fileIndex].Text.Equals("select", StringComparison.InvariantCultureIgnoreCase))
            {
                var selectStatement = new SelectStatementResolver().Resolve(tokens, ref fileIndex, context);
                sources = selectStatement.ChildExpressions;
            }

            if (targets.Count == 0)
            {
                for (int index = 0; index < sources.Count; index++)
                {
                    Expression resolvedSource;

                    if (sources[index].Type.Equals(ExpressionType.COMPLEX) || sources[index].Type.Equals(ExpressionType.CONSTANT))
                    {
                        continue;
                    }
                    else if (sources[index].Type.Equals(ExpressionType.ALIAS))
                    {
                        resolvedSource = sources[index].ChildExpressions[0];
                    }
                    else
                    {
                        resolvedSource = sources[index];
                    }

                    var singleManipulation = new Expression(ExpressionType.COLUMN)
                    {
                        Name = Beautifier.EnhanceNotation(targetObject, InternalConstants.UNRELATED_COLUMN_NAME)
                    };

                    singleManipulation.ChildExpressions.Add(resolvedSource);
                    manipulation.Expressions.Add(singleManipulation);
                }
            }
            else if (StatementResolveHelper.HaveEqualAmountOfRealExpression(sources, targets))
            {
                for (int index = 0; index < targets.Count; index++)
                {
                    if (!sources[index].Type.Equals(ExpressionType.COLUMN) && !sources[index].Type.Equals(ExpressionType.SCALAR_FUNCTION))
                    {
                        continue;
                    }

                    var singleManipulation = new Expression(ExpressionType.COLUMN)
                    {
                        Name = targets[index].Name
                    };

                    singleManipulation.ChildExpressions.Add(sources[index]);
                    manipulation.Expressions.Add(singleManipulation);
                }
            }
            else
            {
                throw new InvalidSqlException("Amount of targets does not match the number of sources");
            }

            if (fileIndex < tokens.Length && tokens[fileIndex].Text.Equals(";"))
            {
                fileIndex++;
            }

            var beautified = new List <Expression>();

            foreach (var exp in manipulation.Expressions)
            {
                beautified.Add(Beautifier.BeautifyColumns(exp, context));
            }

            manipulation.Expressions = beautified;

            return(manipulation);
        }