Пример #1
0
        public NamedTableReference[] GetTableReferencesOfJoin(SourceLocation sourceLocation)
        {
            _tokenStream.ResetToStart();

            // Rewind token stream to the closest FROM

            _tokenStream.SkipTo(sourceLocation);
            _tokenStream.SkipToPrevious(TokenId.FROM);

            // Skip FROM token

            _tokenStream.ReadNext();

            // Read table references

            Stack <TableReferenceScope> scopeStack = new Stack <TableReferenceScope>();
            bool inJoinExpression = false;
            int  expressionDepth  = 0;

            while (_tokenStream.Token.Range.StartLocation < sourceLocation)
            {
                if (_tokenStream.Token.Id == TokenId.JOIN)
                {
                    inJoinExpression = false;
                }
                else if (_tokenStream.Token.Id == TokenId.ON)
                {
                    // Merge top two scopes
                    if (scopeStack.Count >= 2)
                    {
                        TableReferenceScope secondScope = scopeStack.Pop();
                        TableReferenceScope firstScope  = scopeStack.Pop();
                        TableReferenceScope newScope    = new TableReferenceScope();
                        newScope.TableReferences.AddRange(firstScope.TableReferences);
                        newScope.TableReferences.AddRange(secondScope.TableReferences);
                        scopeStack.Push(newScope);
                    }

                    inJoinExpression = true;
                }
                else if (_tokenStream.Token.Id == TokenId.Identifier && !inJoinExpression)
                {
                    // Push named table on stack
                    TableReferenceScope newScope = new TableReferenceScope();
                    scopeStack.Push(newScope);
                    NamedTableReference namedTableReference = ParseTableReference();
                    newScope.TableReferences.Add(namedTableReference);
                }
                else if (_tokenStream.Token.Id == TokenId.LeftParentheses && inJoinExpression)
                {
                    expressionDepth++;
                }
                else if (_tokenStream.Token.Id == TokenId.LeftParentheses && !inJoinExpression)
                {
                    // Push empty scope as marker for nested join start
                    TableReferenceScope newScope = new TableReferenceScope();
                    scopeStack.Push(newScope);
                }
                else if (_tokenStream.Token.Id == TokenId.RightParentheses)
                {
                    if (expressionDepth > 0)
                    {
                        expressionDepth--;
                    }
                    else
                    {
                        inJoinExpression = false;

                        if (scopeStack.Count > 0)
                        {
                            TableReferenceScope newScope = new TableReferenceScope();

                            while (scopeStack.Count > 0)
                            {
                                TableReferenceScope scope = scopeStack.Pop();

                                if (scope.TableReferences.Count == 0)
                                {
                                    break;
                                }

                                newScope.TableReferences.AddRange(scope.TableReferences);
                            }

                            scopeStack.Push(newScope);
                        }
                    }
                }

                _tokenStream.ReadNext();
            }

            if (scopeStack.Count == 0)
            {
                return(new NamedTableReference[0]);
            }
            else
            {
                TableReferenceScope scope = scopeStack.Pop();
                return(scope.TableReferences.ToArray());
            }
        }
Пример #2
0
		public NamedTableReference[] GetTableReferencesOfJoin(SourceLocation sourceLocation)
		{
			_tokenStream.ResetToStart();

			// Rewind token stream to the closest FROM

			_tokenStream.SkipTo(sourceLocation);
			_tokenStream.SkipToPrevious(TokenId.FROM);

			// Skip FROM token

			_tokenStream.ReadNext();

			// Read table references

			Stack<TableReferenceScope> scopeStack = new Stack<TableReferenceScope>();
			bool inJoinExpression = false;
			int expressionDepth = 0;

			while (_tokenStream.Token.Range.StartLocation < sourceLocation)
			{
				if (_tokenStream.Token.Id == TokenId.JOIN)
				{
					inJoinExpression = false;
				}
				else if (_tokenStream.Token.Id == TokenId.ON)
				{
					// Merge top two scopes
					if (scopeStack.Count >= 2)
					{
						TableReferenceScope secondScope = scopeStack.Pop();
						TableReferenceScope firstScope = scopeStack.Pop();
						TableReferenceScope newScope = new TableReferenceScope();
						newScope.TableReferences.AddRange(firstScope.TableReferences);
						newScope.TableReferences.AddRange(secondScope.TableReferences);
						scopeStack.Push(newScope);
					}

					inJoinExpression = true;
				}
				else if (_tokenStream.Token.Id == TokenId.Identifier && !inJoinExpression)
				{
					// Push named table on stack
					TableReferenceScope newScope = new TableReferenceScope();
					scopeStack.Push(newScope);
					NamedTableReference namedTableReference = ParseTableReference();
					newScope.TableReferences.Add(namedTableReference);
				}				
				else if (_tokenStream.Token.Id == TokenId.LeftParentheses && inJoinExpression)
				{
					expressionDepth++;
				}
				else if (_tokenStream.Token.Id == TokenId.LeftParentheses && !inJoinExpression)
				{
					// Push empty scope as marker for nested join start
					TableReferenceScope newScope = new TableReferenceScope();
					scopeStack.Push(newScope);
				}
				else if (_tokenStream.Token.Id == TokenId.RightParentheses)
				{
					if (expressionDepth > 0)
					{
						expressionDepth--;
					}
					else
					{
						inJoinExpression = false;

						if (scopeStack.Count > 0)
						{
							TableReferenceScope newScope = new TableReferenceScope();

							while (scopeStack.Count > 0)
							{
								TableReferenceScope scope = scopeStack.Pop();

								if (scope.TableReferences.Count == 0)
									break;

								newScope.TableReferences.AddRange(scope.TableReferences);
							}

							scopeStack.Push(newScope);
						}
					}
				}

				_tokenStream.ReadNext();
			}

			if (scopeStack.Count == 0)
				return new NamedTableReference[0];
			else
			{
				TableReferenceScope scope = scopeStack.Pop();
				return scope.TableReferences.ToArray();
			}
		}
Пример #3
0
        private TableReferenceScope[] GetTableReferenceScopes(SourceLocation sourceLocation)
        {
            Stack <TableReferenceScope> scopeStack        = new Stack <TableReferenceScope>();
            List <NamedTableReference>  currentReferences = null;
            int  queryDepth               = 0;
            int  parenthesizedDepth       = 0;
            bool endOfCurrentQueryReached = false;
            bool recordTableReferences    = false;
            bool needPopScope             = false;

            _tokenStream.ResetToStart();

            while (!endOfCurrentQueryReached && _tokenStream.Token.Id != TokenId.Eof)
            {
                switch (_tokenStream.Token.Id)
                {
                case TokenId.LeftParentheses:
                    _tokenStream.ReadNext();
                    if (_tokenStream.Token.Id != TokenId.SELECT)
                    {
                        parenthesizedDepth++;
                        _tokenStream.ReadPrevious();
                    }
                    else
                    {
                        queryDepth++;
                        goto case TokenId.SELECT;
                    }
                    break;

                case TokenId.RightParentheses:
                    if (parenthesizedDepth > 0)
                    {
                        parenthesizedDepth--;
                    }
                    else if (queryDepth > 0)
                    {
                        queryDepth--;
                        goto case TokenId.UNION;
                    }
                    break;

                case TokenId.SELECT:
                    TableReferenceScope newScope = new TableReferenceScope();
                    currentReferences = newScope.TableReferences;
                    scopeStack.Push(newScope);
                    break;

                case TokenId.UNION:
                case TokenId.INTERSECT:
                case TokenId.EXCEPT:
                    if (_tokenStream.Token.Range.StartLocation >= sourceLocation)
                    {
                        endOfCurrentQueryReached = true;
                    }
                    needPopScope          = true;
                    recordTableReferences = false;
                    break;

                case TokenId.FROM:
                    recordTableReferences = true;
                    break;

                case TokenId.WHERE:
                case TokenId.GROUP:
                case TokenId.HAVING:
                case TokenId.ORDER:
                    recordTableReferences = false;
                    break;

                case TokenId.Identifier:
                    if (recordTableReferences)
                    {
                        NamedTableReference namedTableReference = ParseTableReference();
                        if (currentReferences != null)
                        {
                            currentReferences.Add(namedTableReference);
                        }
                    }
                    break;
                }

                if (needPopScope && !endOfCurrentQueryReached && scopeStack.Count > 0)
                {
                    scopeStack.Pop();

                    if (scopeStack.Count == 0)
                    {
                        currentReferences = null;
                    }
                    else
                    {
                        currentReferences = scopeStack.Peek().TableReferences;
                    }
                }
                needPopScope = false;

                _tokenStream.ReadNext();
            }

            TableReferenceScope[] result = new TableReferenceScope[scopeStack.Count];
            scopeStack.CopyTo(result, 0);
            return(result);
        }
Пример #4
0
		private TableReferenceScope[] GetTableReferenceScopes(SourceLocation sourceLocation)
		{
			Stack<TableReferenceScope> scopeStack = new Stack<TableReferenceScope>();
			List<NamedTableReference> currentReferences = null;
			int queryDepth = 0;
			int parenthesizedDepth = 0;
			bool endOfCurrentQueryReached = false;
			bool recordTableReferences = false;
			bool needPopScope = false;

			_tokenStream.ResetToStart();

			while (!endOfCurrentQueryReached && _tokenStream.Token.Id != TokenId.Eof)
			{
				switch (_tokenStream.Token.Id)
				{
					case TokenId.LeftParentheses:
						_tokenStream.ReadNext();
						if (_tokenStream.Token.Id != TokenId.SELECT)
						{
							parenthesizedDepth++;
							_tokenStream.ReadPrevious();
						}
						else
						{
							queryDepth++;
							goto case TokenId.SELECT;
						}
						break;

					case TokenId.RightParentheses:
						if (parenthesizedDepth > 0)
							parenthesizedDepth--;
						else if (queryDepth > 0)
						{
							queryDepth--;
							goto case TokenId.UNION;
						}
						break;

					case TokenId.SELECT:
						TableReferenceScope newScope = new TableReferenceScope();
						currentReferences = newScope.TableReferences;
						scopeStack.Push(newScope);
						break;

					case TokenId.UNION:
					case TokenId.INTERSECT:
					case TokenId.EXCEPT:
						if (_tokenStream.Token.Range.StartLocation >= sourceLocation)
							endOfCurrentQueryReached = true;
						needPopScope = true;
						recordTableReferences = false;
						break;

					case TokenId.FROM:
						recordTableReferences = true;
						break;

					case TokenId.WHERE:
					case TokenId.GROUP:
				    case TokenId.HAVING:
					case TokenId.ORDER:
						recordTableReferences = false;
						break;

					case TokenId.Identifier:
						if (recordTableReferences)
						{
							NamedTableReference namedTableReference = ParseTableReference();
							if (currentReferences != null)
								currentReferences.Add(namedTableReference);
						}
						break;
				}

				if (needPopScope && !endOfCurrentQueryReached && scopeStack.Count > 0)
				{
					scopeStack.Pop();

					if (scopeStack.Count == 0)
						currentReferences = null;
					else
						currentReferences = scopeStack.Peek().TableReferences;
				}
				needPopScope = false;

				_tokenStream.ReadNext();
			}

			TableReferenceScope[] result = new TableReferenceScope[scopeStack.Count];
			scopeStack.CopyTo(result, 0);
			return result;
		}