internal DBSqlParserTable FindTableForColumn( DBSqlParserColumn column ) { DBSqlParserTableCollection tables = Tables; int tableCount = tables.Count; for (int i = 0; i < tableCount; ++i) { DBSqlParserTable table = tables[i]; // if the table name matches the correlation name, then we're certain // of a match if (string.Empty == column.DatabaseName && string.Empty == column.SchemaName && CatalogMatch(column.TableName, table.CorrelationName)) { return(table); } // otherwise, compare each part of the name (if they exist) with the // table and pick the one that matches all the parts that exist. if ((string.Empty == column.DatabaseName || CatalogMatch(column.DatabaseName, table.DatabaseName)) && (string.Empty == column.SchemaName || CatalogMatch(column.SchemaName, table.SchemaName)) && (string.Empty == column.TableName || CatalogMatch(column.TableName, table.TableName))) { return(table); } } Debug.Assert(false, "Why didn't we find a match for the column?"); return(null); }
private void Parse2( string statementText ) { // Debug.WriteLine(statementText); PARSERSTATE parserState = PARSERSTATE.NOTHINGYET; Token[] namePart = new Token[4]; int currentPart = 0; Token alias = Token.Null; TokenType lastTokenType = TokenType.Null; int parenLevel = 0; // bool distinctFound; _columns = null; _tables = null; Match match = SqlTokenParser.Match(statementText); Token token = TokenFromMatch(match); while (true) { // Debug.WriteLine(String.Format("{0,-15} {1,-17} {2} {3}", parserState, token.Type.ToString(), parenLevel, token.Value)); switch (parserState) { case PARSERSTATE.DONE: return; case PARSERSTATE.NOTHINGYET: switch (token.Type) { case TokenType.Keyword_SELECT: parserState = PARSERSTATE.SELECT; break; default: Debug.Assert(false, "no state defined!!!!we should never be here!!!"); throw ADP.InvalidOperation(Res.GetString(Res.ADP_SQLParserInternalError)); } break; case PARSERSTATE.SELECT: switch (token.Type) { case TokenType.Identifier: case TokenType.QuotedIdentifier: parserState = PARSERSTATE.COLUMN; currentPart = 0; namePart[0] = token; break; case TokenType.Keyword_FROM: parserState = PARSERSTATE.FROM; break; case TokenType.Other_Star: parserState = PARSERSTATE.COLUMNALIAS; currentPart = 0; namePart[0] = token; break; case TokenType.Keyword_DISTINCT: // distinctFound = true; break; case TokenType.Keyword_ALL: break; case TokenType.Other_LeftParen: parserState = PARSERSTATE.EXPRESSION; parenLevel++; break; case TokenType.Other_RightParen: throw ADP.SyntaxErrorMissingParenthesis(); default: parserState = PARSERSTATE.EXPRESSION; break; } break; case PARSERSTATE.COLUMN: switch (token.Type) { case TokenType.Identifier: case TokenType.QuotedIdentifier: if (TokenType.Other_Period != lastTokenType) { parserState = PARSERSTATE.COLUMNALIAS; alias = token; } else { namePart[++currentPart] = token; } break; case TokenType.Other_Period: if (currentPart > 3) { throw ADP.SyntaxErrorTooManyNameParts(); } break; case TokenType.Other_Star: parserState = PARSERSTATE.COLUMNALIAS; namePart[++currentPart] = token; break; case TokenType.Keyword_AS: break; case TokenType.Keyword_FROM: case TokenType.Other_Comma: parserState = (token.Type == TokenType.Keyword_FROM) ? PARSERSTATE.FROM : PARSERSTATE.SELECT; AddColumn(currentPart, namePart, alias); currentPart = -1; alias = Token.Null; break; case TokenType.Other_LeftParen: parserState = PARSERSTATE.EXPRESSION; parenLevel++; currentPart = -1; break; case TokenType.Other_RightParen: throw ADP.SyntaxErrorMissingParenthesis(); default: parserState = PARSERSTATE.EXPRESSION; currentPart = -1; break; } break; case PARSERSTATE.COLUMNALIAS: switch (token.Type) { case TokenType.Keyword_FROM: case TokenType.Other_Comma: parserState = (token.Type == TokenType.Keyword_FROM) ? PARSERSTATE.FROM : PARSERSTATE.SELECT; AddColumn(currentPart, namePart, alias); currentPart = -1; alias = Token.Null; break; default: throw ADP.SyntaxErrorExpectedCommaAfterColumn(); } break; case PARSERSTATE.EXPRESSION: switch (token.Type) { case TokenType.Identifier: case TokenType.QuotedIdentifier: if (0 == parenLevel) { alias = token; } break; case TokenType.Keyword_FROM: case TokenType.Other_Comma: if (0 == parenLevel) { parserState = (token.Type == TokenType.Keyword_FROM) ? PARSERSTATE.FROM : PARSERSTATE.SELECT; AddColumn(currentPart, namePart, alias); currentPart = -1; alias = Token.Null; } else { if (token.Type == TokenType.Keyword_FROM) { throw ADP.SyntaxErrorUnexpectedFrom(); } } break; case TokenType.Other_LeftParen: parenLevel++; break; case TokenType.Other_RightParen: parenLevel--; break; } break; case PARSERSTATE.FROM: switch (token.Type) { case TokenType.Identifier: case TokenType.QuotedIdentifier: parserState = PARSERSTATE.TABLE; currentPart = 0; namePart[0] = token; break; default: throw ADP.SyntaxErrorExpectedIdentifier(); } break; case PARSERSTATE.TABLE: switch (token.Type) { case TokenType.Identifier: case TokenType.QuotedIdentifier: if (TokenType.Other_Period != lastTokenType) { parserState = PARSERSTATE.TABLEALIAS; alias = token; } else { namePart[++currentPart] = token; } break; case TokenType.Other_Period: if (currentPart > 2) { throw ADP.SyntaxErrorTooManyNameParts(); } break; case TokenType.Keyword_AS: break; case TokenType.Keyword_COMPUTE: case TokenType.Keyword_FOR: case TokenType.Keyword_GROUP: case TokenType.Keyword_HAVING: case TokenType.Keyword_INTERSECT: case TokenType.Keyword_MINUS: case TokenType.Keyword_ORDER: case TokenType.Keyword_UNION: case TokenType.Keyword_WHERE: case TokenType.Null: case TokenType.Other_Comma: parserState = (TokenType.Other_Comma == token.Type) ? PARSERSTATE.FROM : PARSERSTATE.DONE; AddTable(currentPart, namePart, alias); currentPart = -1; alias = Token.Null; break; default: throw ADP.SyntaxErrorExpectedNextPart(); } break; case PARSERSTATE.TABLEALIAS: switch (token.Type) { case TokenType.Keyword_COMPUTE: case TokenType.Keyword_FOR: case TokenType.Keyword_GROUP: case TokenType.Keyword_HAVING: case TokenType.Keyword_INTERSECT: case TokenType.Keyword_MINUS: case TokenType.Keyword_ORDER: case TokenType.Keyword_UNION: case TokenType.Keyword_WHERE: case TokenType.Null: case TokenType.Other_Comma: parserState = (TokenType.Other_Comma == token.Type) ? PARSERSTATE.FROM : PARSERSTATE.DONE; AddTable(currentPart, namePart, alias); currentPart = -1; alias = Token.Null; break; default: throw ADP.SyntaxErrorExpectedCommaAfterTable(); } break; default: Debug.Assert(false, "no state defined!!!!we should never be here!!!"); throw ADP.InvalidOperation(Res.GetString(Res.ADP_SQLParserInternalError)); } lastTokenType = token.Type; match = match.NextMatch(); token = TokenFromMatch(match); } }
private void CompleteSchemaInformation() { DBSqlParserColumnCollection columns = Columns; DBSqlParserTableCollection tables = Tables; int columnCount = columns.Count; int tableCount = tables.Count; // First, derive all of the information we can about each table for (int i = 0; i < tableCount; i++) { DBSqlParserTable table = tables[i]; DBSqlParserColumnCollection tableColumns = GatherTableColumns(table); table.Columns = tableColumns; } // Next, derive all of the column information we can. for (int i = 0; i < columnCount; i++) { DBSqlParserColumn column = columns[i]; DBSqlParserTable table = FindTableForColumn(column); if (!column.IsExpression) { // If this is a '*' column, then we have to expand the '*' into // its component parts. if ("*" == column.ColumnName) { // Remove the existing "*" column entry and replace it with the // complete list of columns in the table. columns.RemoveAt(i); // If this is a tablename.* column, then add references to the // all columns in the specified table, otherwise add references // to all columns in all tables. if (String.Empty != column.TableName) { DBSqlParserColumnCollection tableColumns = table.Columns; int tableColumnCount = tableColumns.Count; for (int j = 0; j < tableColumnCount; ++j) { columns.Insert(i + j, tableColumns[j]); } columnCount += tableColumnCount - 1; // don't forget to adjust our loop end i += tableColumnCount - 1; } else { for (int k = 0; k < tableCount; k++) { table = tables[k]; DBSqlParserColumnCollection tableColumns = table.Columns; int tableColumnCount = tableColumns.Count; for (int j = 0; j < tableColumnCount; ++j) { columns.Insert(i + j, tableColumns[j]); } columnCount += tableColumnCount - 1; // don't forget to adjust our loop end i += tableColumnCount; } } } else { // if this isn't a '*' column, we find the table that the column belongs // to, and ask it's column collection for the completed column info (that // contains information about key values, etc.) DBSqlParserColumn completedColumn = FindCompletedColumn(table, column); if (null != completedColumn) // MDAC 87152 { column.CopySchemaInfoFrom(completedColumn); } else { column.CopySchemaInfoFrom(table); } } } } // Finally, derive the key column information for each table for (int i = 0; i < tableCount; i++) { DBSqlParserTable table = tables[i]; GatherKeyColumns(table); } }