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()); } }
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(); } }
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); }
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; }