private static OraclePlSqlParameter ResolveParameter(StatementGrammarNode parameterDeclaration) { var parameter = new OraclePlSqlParameter { DefinitionNode = parameterDeclaration, Name = parameterDeclaration[Terminals.ParameterIdentifier].Token.Value.ToQuotedIdentifier() }; var direction = ParameterDirection.Input; var parameterDirectionDeclaration = parameterDeclaration[NonTerminals.ParameterDirectionDeclaration]; if (parameterDirectionDeclaration != null) { if (parameterDirectionDeclaration[Terminals.Out] != null) { direction = parameterDeclaration[Terminals.In] == null ? ParameterDirection.Output : ParameterDirection.InputOutput; } parameter.DataTypeNode = parameterDirectionDeclaration[NonTerminals.PlSqlDataTypeWithoutConstraint]; parameter.DataType = OracleReferenceBuilder.ResolveDataTypeFromNode(parameter.DataTypeNode); parameter.DefaultExpressionNode = parameterDirectionDeclaration[NonTerminals.VariableDeclarationDefaultValue]; } else { parameter.DataType = OracleDataType.Empty; } parameter.Direction = direction; return(parameter); }
private static ToolTipObject BuildExpectedTokenListToolTip(StatementGrammarNode node) { var candidates = OracleSqlParser.Instance.GetTerminalCandidates(node.LastTerminalNode) .Where(c => !TerminalCandidatesToSkip.Contains(c.Id)) .ToArray(); if (candidates.Length == 0) { return(null); } var candidateLabels = candidates .Select(c => c.ToString()) .Distinct() .OrderBy(l => l); var candidateList = String.Join(Environment.NewLine, candidateLabels); var stackPanel = new StackPanel(); stackPanel.Children.Add(new TextBlock(new Bold(new Run("Expecting one of the following: ")))); stackPanel.Children.Add( new TextBox { Text = candidateList, IsReadOnly = true, IsReadOnlyCaretVisible = true, Background = Brushes.Transparent, BorderThickness = new Thickness() }); return(new ToolTipObject { Content = stackPanel }); }
private static void BuildCommonDateFormatCompletionItems(StatementGrammarNode currentNode, ICollection<ICodeCompletionItem> completionItems) { completionItems.Add(BuildParameterCompletionItem(currentNode, "DL", "DL - long date format - NLS dependent")); completionItems.Add(BuildParameterCompletionItem(currentNode, "DS", "DS - short date format - NLS dependent")); completionItems.Add(BuildParameterCompletionItem(currentNode, "TS", "TS - short time format - NLS dependent")); completionItems.Add(BuildParameterCompletionItem(currentNode, "YYYY-MM-DD", $"YYYY-MM-DD - ISO date - {DateTime.Now:yyyy-MM-dd}")); completionItems.Add(BuildParameterCompletionItem(currentNode, "YYYY-MM-DD HH24:MI:SS", $"YYYY-MM-DD HH24:MI:SS - ISO date time - {DateTime.Now:yyyy-MM-dd HH:mm:ss}")); completionItems.Add(BuildParameterCompletionItem(currentNode, "YYYY-MM-DD\"T\"HH24:MI:SS", $"YYYY-MM-DD\"T\"HH24:MI:SS - XML date time - {DateTime.Now:yyyy-MM-dd\"T\"HH:mm:ss}")); completionItems.Add(BuildParameterCompletionItem(currentNode, "YYYY-MM-DD HH24:MI:SS.FF9 TZH:TZM", $"YYYY-MM-DD HH24:MI:SS.FF9 TZH:TZM - {DateTime.Now:yyyy-MM-dd HH:mm:ss.ffffff000 zzz}")); completionItems.Add(BuildParameterCompletionItem(currentNode, "DY, DD MON YYYY HH24:MI:SS TZD", $"DY, DD MON YYYY HH24:MI:SS TZD - {DateTime.Now:r} - NLS dependent")); completionItems.Add(BuildParameterCompletionItem(currentNode, "DAY", "DAY (NAME OF DAY); Day (Name of day), padded with blanks to display width of the widest name of day in the date language used for this element")); completionItems.Add(BuildParameterCompletionItem(currentNode, "D", "D - Day of week (1-7)")); completionItems.Add(BuildParameterCompletionItem(currentNode, "DD", "DD - Day of month (1-31)")); completionItems.Add(BuildParameterCompletionItem(currentNode, "DDD", "DDD - Day of year (1-366)")); completionItems.Add(BuildParameterCompletionItem(currentNode, "MON", "MON - Abbreviated name of month")); completionItems.Add(BuildParameterCompletionItem(currentNode, "MONTH", "MONTH - Name of month, padded with blanks to display width of the widest name of month in the date language used for this element")); completionItems.Add(BuildParameterCompletionItem(currentNode, "SSSSS", "SSSSS - Seconds past midnight (0-86399)")); completionItems.Add(BuildParameterCompletionItem(currentNode, "RM", "RM - Roman numeral month (I-XII; January = I)")); completionItems.Add(BuildParameterCompletionItem(currentNode, "TZD", "TZD - Daylight savings information; the TZD value is an abbreviated time zone string with daylight savings information. It must correspond with the region specified in TZR. ")); completionItems.Add(BuildParameterCompletionItem(currentNode, "TZH", "TZH - Time zone hour")); completionItems.Add(BuildParameterCompletionItem(currentNode, "TZM", "TZM - Time zone minute")); completionItems.Add(BuildParameterCompletionItem(currentNode, "TZR", "TZR - Time zone region information; the value must be one of the time zone regions supported in the database. ")); completionItems.Add(BuildParameterCompletionItem(currentNode, "Y", "Y - Last digit of year")); completionItems.Add(BuildParameterCompletionItem(currentNode, "YY", "YY - Last two digits of year")); completionItems.Add(BuildParameterCompletionItem(currentNode, "YYY", "YYY - Last three digits of year")); }
private static bool CanConvertCurrentTerminal(StatementGrammarNode currentTerminal) { return (currentTerminal.Id.In(Terminals.NumberLiteral, Terminals.StringLiteral) && (currentTerminal.RootNode[0, 0].Id.In(NonTerminals.SelectStatement, NonTerminals.UpdateStatement, NonTerminals.DeleteStatement, NonTerminals.InsertStatement, NonTerminals.MergeStatement) || currentTerminal.RootNode.Id == NonTerminals.PlSqlBlockStatement)); }
private void ResolveSubProgramDefinitions(OraclePlSqlProgram program, StatementGrammarNode node) { foreach (var childNode in node.ChildNodes) { var subProgram = program; var isPlSqlBlock = String.Equals(childNode.Id, NonTerminals.PlSqlBlock); var isFunction = String.Equals(childNode.Id, NonTerminals.FunctionDefinition); if (isPlSqlBlock || String.Equals(childNode.Id, NonTerminals.ProcedureDefinition) || isFunction) { var nameTerminal = childNode[0]?[Terminals.Identifier]; var programType = isPlSqlBlock ? PlSqlProgramType.PlSqlBlock : PlSqlProgramType.NestedProgram; subProgram = new OraclePlSqlProgram(nameTerminal?.Token.Value.ToQuotedIdentifier(), isFunction ? ProgramType.PackageFunction : ProgramType.PackageProcedure, programType, this) { Owner = program, RootNode = childNode, ObjectIdentifier = program.ObjectIdentifier }; ResolveSqlStatements(subProgram); ResolveParameterDeclarations(subProgram); ResolveLocalVariableTypeAndLabelDeclarations(subProgram); program.SubPrograms.Add(subProgram); } ResolveSubProgramDefinitions(subProgram, childNode); } }
public static OracleDataType ResolveDataTypeFromJsonDataTypeNode(StatementGrammarNode jsonDataTypeNode) { if (jsonDataTypeNode == null) { return(OracleDataType.Empty); } if (!String.Equals(jsonDataTypeNode.Id, NonTerminals.JsonDataType)) { throw new ArgumentException($"Node ID must be '{NonTerminals.JsonDataType}'. ", nameof(jsonDataTypeNode)); } var dataTypeNode = jsonDataTypeNode[NonTerminals.DataType]; if (dataTypeNode != null) { return(ResolveDataTypeFromNode(dataTypeNode)); } var typeTerminal = jsonDataTypeNode[0]; return (typeTerminal == null ? OracleDataType.Empty : new OracleDataType { FullyQualifiedName = OracleObjectIdentifier.Create(null, ((OracleToken)typeTerminal.Token).UpperInvariantValue) }); }
public ICollection <TerminalCandidate> GetTerminalCandidates(StatementGrammarNode node) { var candidates = new HashSet <TerminalCandidate>(); var nonTerminalIds = new List <SqlGrammarRuleSequenceNonTerminal>(); if (node != null) { if (node.Type != NodeType.Terminal) { throw new ArgumentException("Node must be a terminal node. ", nameof(node)); } MatchNode(node, candidates); } else { nonTerminalIds.AddRange(AvailableNonTerminals); } foreach (var nonTerminalId in nonTerminalIds) { GatherCandidatesFromNonterminal(nonTerminalId, candidates); } return(candidates); }
private void ResolveParameterDeclarations(OraclePlSqlProgram program) { StatementGrammarNode parameterSourceNode; switch (program.RootNode.Id) { case NonTerminals.CreateFunction: parameterSourceNode = program.RootNode[NonTerminals.PlSqlFunctionSource]; break; case NonTerminals.CreateProcedure: parameterSourceNode = program.RootNode; break; default: parameterSourceNode = program.RootNode[0]; break; } var returnParameterNode = parameterSourceNode?[NonTerminals.PlSqlDataTypeWithoutConstraint]; var parameterPosition = 0; if (returnParameterNode != null) { program.ReturnParameter = new OraclePlSqlParameter { DefinitionNode = parameterSourceNode, Direction = ParameterDirection.ReturnValue, Nullable = true, DataTypeNode = returnParameterNode }; var returnTypeName = String.Concat(returnParameterNode.Terminals.Select(t => t.Token.Value)); program.Metadata.AddParameter(new OracleProgramParameterMetadata(null, parameterPosition, parameterPosition, 0, ParameterDirection.ReturnValue, returnTypeName, OracleObjectIdentifier.Empty, false)); parameterPosition++; } var parameterDeclarationList = parameterSourceNode?[NonTerminals.ParenthesisEnclosedParameterDeclarationList, NonTerminals.ParameterDeclarationList]; if (parameterDeclarationList == null) { return; } var parameterDeclarations = StatementGrammarNode.GetAllChainedClausesByPath(parameterDeclarationList, null, NonTerminals.ParameterDeclarationListChained, NonTerminals.ParameterDeclarationList) .Select(n => n[NonTerminals.ParameterDeclaration]); foreach (var parameterDeclaration in parameterDeclarations) { var parameter = ResolveParameter(parameterDeclaration); program.Parameters.Add(parameter); var parameterMetadata = new OracleProgramParameterMetadata(parameter.Name, parameterPosition, parameterPosition, 0, parameter.Direction, parameter.DataType.IsPrimitive ? parameter.DataType.FullyQualifiedName.NormalizedName : null, parameter.DataType.IsPrimitive ? OracleObjectIdentifier.Empty : parameter.DataType.FullyQualifiedName, parameter.DefaultExpressionNode != null); program.Metadata.AddParameter(parameterMetadata); parameterPosition++; } }
private bool IsTerminalSelected(StatementGrammarNode terminal) { var isWithinSelection = terminal.SourcePosition.IndexEnd + 1 >= ExecutionContext.SelectionStart && terminal.SourcePosition.IndexStart <= ExecutionContext.SelectionEnd; return(isWithinSelection && ExecutionContext.SelectionLength == 0 ? terminal.Id.IsIdentifier() && !String.Equals(terminal.Id, OracleGrammarDescription.Terminals.BindVariableIdentifier) : terminal.SourcePosition.IndexEnd + 1 > ExecutionContext.SelectionStart && terminal.SourcePosition.IndexStart < ExecutionContext.SelectionEnd); }
private static SourcePosition FindDescendantPositionToExchange(StatementGrammarNode movedNode) { var nodeToExchange = movedNode.ParentNode .GetPathFilterDescendants(n => n != movedNode && NodeFilters.BreakAtNestedQueryBlock(n), movedNode.Id) .FirstOrDefault(); return(CreateNodePosition(movedNode, nodeToExchange)); }
public OracleSpecialTableReference(OracleReferenceContainer referenceContainer, ReferenceType referenceType, IEnumerable <OracleSelectListColumn> columns, StatementGrammarNode columnsClause) : base(referenceType) { referenceContainer.ObjectReferences.Add(this); Container = referenceContainer; ColumnDefinitions = columns.ToArray(); ColumnsClause = columnsClause; }
private static string GetRequiredPrecedingTerminalId(StatementGrammarNode terminal) { var precedingTerminal = terminal.PrecedingTerminal; return(precedingTerminal != null && precedingTerminal.Id.In(Terminals.Date, Terminals.Timestamp) ? precedingTerminal.Id : null); }
public static bool TryCreatePlSqlDataTypeReference(OraclePlSqlProgram program, StatementGrammarNode dataTypeNode, out OracleDataTypeReference dataTypeReference) { StatementGrammarNode ownerNode = null; StatementGrammarNode typeIdentifier = null; var firstChild = dataTypeNode[0]; switch (firstChild?.Id) { case NonTerminals.AssignmentStatementTarget: var plSqlAssignmentTarget = firstChild[NonTerminals.PlSqlAssignmentTarget]; var percentCharacterTypeOrRowTypeNotFound = dataTypeNode.ChildNodes.Count == 1; if (percentCharacterTypeOrRowTypeNotFound && plSqlAssignmentTarget != null) { var chainedIdentifiers = GatherChainedIdentifiers(plSqlAssignmentTarget).ToList(); if (chainedIdentifiers.Count <= 2) { typeIdentifier = chainedIdentifiers.LastOrDefault(); ownerNode = chainedIdentifiers.FirstOrDefault(i => i != typeIdentifier); } } break; case NonTerminals.BuiltInDataType: typeIdentifier = firstChild.FirstTerminalNode; break; default: if (String.Equals(dataTypeNode.Id, NonTerminals.AssociativeArrayIndexType)) { typeIdentifier = dataTypeNode.FirstTerminalNode; } break; } dataTypeReference = null; if (typeIdentifier == null) { return(false); } dataTypeReference = new OracleDataTypeReference { RootNode = dataTypeNode, Container = program, OwnerNode = ownerNode, ObjectNode = typeIdentifier }; ResolveTypeMetadata(dataTypeReference); program.DataTypeReferences.Add(dataTypeReference); return(true); }
public static OracleObjectIdentifier Create(StatementGrammarNode ownerNode, StatementGrammarNode objectNode, StatementGrammarNode aliasNode) { var ownerName = ownerNode?.Token.Value; var tableName = aliasNode == null ? objectNode?.Token.Value : aliasNode.Token.Value; return(Create(ownerName, tableName)); }
private static StatementGrammarNode TryGetOptionalAncestor(StatementGrammarNode node) { while (node != null && node.IsRequired) { node = node.ParentNode; } return(node); }
public static OracleDataType ResolveDataTypeFromNode(StatementGrammarNode dataType) { var dataTypeReference = new OracleDataTypeReference { RootNode = dataType }; ResolveTypeMetadata(dataTypeReference); return(dataTypeReference.ResolvedDataType); }
private static StatementGrammarNode FindCondition(StatementGrammarNode rootNode) { if (!String.Equals(rootNode.ParentNode.Id, NonTerminals.Expression)) { return(null); } return(rootNode.GetAncestor(NonTerminals.Condition)); }
private static IEnumerable <StatementGrammarNode> GetFunctionCallNodes(StatementGrammarNode identifier) { var parenthesisEnclosedFunctionParametersNode = identifier.ParentNode.ParentNode[NonTerminals.ParenthesisEnclosedFunctionParameters]; if (parenthesisEnclosedFunctionParametersNode != null) { yield return(parenthesisEnclosedFunctionParametersNode); } }
private void AnalyzeDataType(StatementGrammarNode effectiveTerminal) { var dataTypeNode = effectiveTerminal.GetPathFilterAncestor(n => !String.Equals(n.Id, NonTerminals.Expression), NonTerminals.DataType); if (dataTypeNode == null) { return; } ReferenceIdentifier = BuildReferenceIdentifier(dataTypeNode.GetDescendants(Terminals.SchemaIdentifier, Terminals.DataTypeIdentifier).ToArray()); }
public void SetUp() { const string sqlText = "WITH XXX AS (SELECT 3 COL FROM DUAL CTE_OUTER_ALIAS_1) SELECT VP1 COL1, (SELECT 1 FROM XXX SC_ALIAS_1) SCALARSUBQUERY FROM (WITH YYY AS (SELECT 1 FROM SYS.DUAL CTE_INNER_ALIAS_1), ZZZ AS (SELECT 2 FROM DUAL CTE_INNER_ALIAS_2), FFF AS (SELECT 4 FROM XXX CTE_INNER_ALIAS_3) SELECT COL + 1 VP1 FROM (SELECT COL FROM XXX TABLE_ALIAS_1, DUAL TABLE_ALIAS_2) TABLE_ALIAS_3) SUBQUERY"; var result = OracleSqlParser.Instance.Parse(sqlText); result.Count.ShouldBe(1); var oracleStatement = result.Single(); oracleStatement.ParseStatus.ShouldBe(ParseStatus.Success); _rootNode = oracleStatement.RootNode; }
private void ResolveCurrentTerminalValue(StatementGrammarNode terminal) { var isCursorAfterColon = CursorPosition == terminal.SourcePosition.IndexEnd + 1 && String.Equals(terminal.Id, Terminals.Colon); TerminalValueUnderCursor = isCursorAfterColon ? String.Empty : terminal.Token.Value; TerminalValuePartUntilCaret = isCursorAfterColon || CursorPosition > terminal.SourcePosition.IndexEnd + 1 ? String.Empty : terminal.Token.Value.Substring(0, CursorPosition - terminal.SourcePosition.IndexStart).Trim('"'); }
private OracleObjectIdentifier CreateObjectIdentifierFromSchemaObjectNode(StatementGrammarNode schemaObjectNode) { if (schemaObjectNode == null) { return(OracleObjectIdentifier.Empty); } var owner = schemaObjectNode[NonTerminals.SchemaPrefix, Terminals.SchemaIdentifier]?.Token.Value ?? DatabaseModel.CurrentSchema; var name = schemaObjectNode[Terminals.ObjectIdentifier]?.Token.Value; return(OracleObjectIdentifier.Create(owner, name)); }
protected override CommandCanExecuteResult CanExecute() { if (CurrentNode == null || CurrentNode != CurrentNode.Statement.RootNode.FirstTerminalNode) { return(false); } _sourceNode = CurrentQueryBlock != null && String.Equals(CurrentNode.Id, Terminals.Select) ? CurrentQueryBlock.RootNode : CurrentNode.Statement.RootNode; return(GetReplacedSegments().Any()); }
private static int?GetSimplePrecisionValue(StatementGrammarNode simplePrecisionNode, out StatementGrammarNode node) { if (simplePrecisionNode == null) { node = null; return(null); } node = simplePrecisionNode[Terminals.IntegerLiteral]; return(node == null ? (int?)null : Convert.ToInt32(node.Token.Value)); }
private static SourcePosition FindAncestorPositionToExchange(StatementGrammarNode movedNode) { var parentCandidate = movedNode.ParentNode.ParentNode; StatementGrammarNode nodeToExchange = null; while (parentCandidate != null && nodeToExchange == null) { nodeToExchange = parentCandidate.ChildNodes.FirstOrDefault(n => String.Equals(n.Id, movedNode.Id)); parentCandidate = parentCandidate.ParentNode; } return(CreateNodePosition(movedNode, nodeToExchange)); }
private void AnalyzeQueryTableExpression(StatementGrammarNode effectiveTerminal) { var queryTableExpression = effectiveTerminal.GetPathFilterAncestor(n => !n.Id.In(NonTerminals.InnerTableReference, NonTerminals.QueryBlock), NonTerminals.QueryTableExpression); if (queryTableExpression == null) { return; } var identifiers = queryTableExpression.GetPathFilterDescendants(n => !n.Id.In(NonTerminals.Expression, NonTerminals.NestedQuery), Terminals.SchemaIdentifier, Terminals.ObjectIdentifier, Terminals.Identifier).ToArray(); ReferenceIdentifier = BuildReferenceIdentifier(identifiers); }
private static LineBreakPosition GetSelectBreakPosition(StatementGrammarNode node) { var breakPosition = String.Equals(node.PrecedingTerminal?.Id, Terminals.LeftParenthesis) ? LineBreakPosition.BeforeNode | LineBreakPosition.AfterNode : LineBreakPosition.AfterNode; if (HasQueryBlockDistinctModifier(node)) { breakPosition ^= LineBreakPosition.AfterNode; } return(breakPosition); }
private static int?NavigateToColumnDefinition(OracleQueryBlock queryBlock, StatementGrammarNode terminal) { var column = queryBlock.AllColumnReferences.SingleOrDefault(c => c.ColumnNode == terminal); if (column?.ValidObjectReference == null || column.ValidObjectReference.QueryBlocks.Count != 1) { return(null); } var childQueryBlock = column.ValidObjectReference.QueryBlocks.Single(); return(NavigateThroughQueryBlock(childQueryBlock, column.NormalizedName)); }
protected override TextSegment ResolveAddedTextSegment() { var groupByClause = CurrentQueryBlock.RootNode[NonTerminals.GroupByClause]; if (groupByClause == null) { var targetNode = CurrentQueryBlock.RootNode[NonTerminals.HierarchicalQueryClause] ?? CurrentQueryBlock.RootNode[NonTerminals.WhereClause] ?? CurrentQueryBlock.FromClause; if (targetNode?.LastTerminalNode != null) { return (new TextSegment { IndextStart = targetNode.LastTerminalNode.SourcePosition.IndexEnd + 1, Length = 0, Text = $" GROUP BY {ExpressionText}" }); } return(TextSegment.Empty); } var groupingExpressions = groupByClause.GetPathFilterDescendants(n => !n.Id.In(NonTerminals.GroupingSetsClause, NonTerminals.RollupCubeClause, NonTerminals.NestedQuery, NonTerminals.HavingClause), NonTerminals.GroupingClause) .Where(n => n.ChildNodes.Count > 0 && String.Equals(n.ChildNodes[0].Id, NonTerminals.Expression)); StatementGrammarNode lastGroupingExpression = null; foreach (var groupingExpression in groupingExpressions) { if (TerminalCollectionEqual(groupingExpression.Terminals, SelectedTerminals)) { return(TextSegment.Empty); } lastGroupingExpression = groupingExpression; } var commaPrefix = lastGroupingExpression == null ? String.Empty : ", "; return (new TextSegment { IndextStart = (lastGroupingExpression?.SourcePosition.IndexEnd ?? groupByClause.SourcePosition.IndexEnd) + 1, Length = 0, Text = $"{commaPrefix}{ExpressionText}" }); }
private static OracleObjectIdentifier GetObjectIdentifierFromNode(StatementGrammarNode node) { if (node == null) { return(OracleObjectIdentifier.Empty); } var schemaIdentifierTerminal = node[NonTerminals.SchemaPrefix, Terminals.SchemaIdentifier]; var objectIdentifierTerminal = node[Terminals.ObjectIdentifier]; return(objectIdentifierTerminal == null ? OracleObjectIdentifier.Empty : OracleObjectIdentifier.Create(schemaIdentifierTerminal, objectIdentifierTerminal, null)); }
private FindUsagesCommand(ActionExecutionContext executionContext) { if (executionContext.DocumentRepository == null || executionContext.DocumentRepository.StatementText != executionContext.StatementText) { return; } _currentNode = GetFindUsagesCompatibleTerminal(executionContext.DocumentRepository.Statements, executionContext.CaretOffset); if (_currentNode == null) { return; } _semanticModel = (OracleStatementSemanticModel)executionContext.DocumentRepository.ValidationModels[_currentNode.Statement].SemanticModel; _queryBlock = _semanticModel.GetQueryBlock(_currentNode); _executionContext = executionContext; }
private async Task ConfigureSettings(CancellationToken cancellationToken) { ExecutionContext.EnsureSettingsProviderAvailable(); _settingsModel = ExecutionContext.SettingsProvider.Settings; _settingsModel.IsTextInputVisible = false; var expandedColumns = new List<ColumnDescriptionItem>(); var databaseLinkReferences = new List<OracleObjectWithColumnsReference>(); _asteriskNode = FillColumnNames(expandedColumns, databaseLinkReferences, true); var useDefaultSettings = _settingsModel.UseDefaultSettings == null || _settingsModel.UseDefaultSettings(); foreach (var databaseLinkReference in databaseLinkReferences) { var databaseLinkIdentifier = String.Concat(databaseLinkReference.DatabaseLinkNode.Terminals.Select(t => t.Token.Value)); var remoteObjectIdenrifier = OracleObjectIdentifier.Create(databaseLinkReference.OwnerNode, databaseLinkReference.ObjectNode, null); var columnNames = await CurrentQueryBlock.SemanticModel.DatabaseModel.GetRemoteTableColumnsAsync(databaseLinkIdentifier, remoteObjectIdenrifier, cancellationToken); expandedColumns.AddRange( columnNames.Select( n => new ColumnDescriptionItem { OwnerIdentifier = databaseLinkReference.FullyQualifiedObjectName, ColumnName = n.ToSimpleIdentifier() })); } foreach (var expandedColumn in expandedColumns.Distinct(c => c.ColumnNameLabel)) { _settingsModel.AddBooleanOption( new BooleanOption { OptionIdentifier = expandedColumn.ColumnNameLabel, DescriptionContent = BuildColumnOptionDescription(expandedColumn), Value = !expandedColumn.IsPseudocolumn && !expandedColumn.IsHidden && useDefaultSettings, Tag = expandedColumn }); } _settingsModel.Title = "Expand Asterisk"; _settingsModel.Heading = _settingsModel.Title; }
public static ICollection<CommandExecutionHandler> ResolveCommandHandlers(OracleStatementSemanticModel semanticModel, StatementGrammarNode currentTerminal) { CheckParametersNotNull(semanticModel, currentTerminal); var commands = new List<CommandExecutionHandler>(); if (!CanConvertCurrentTerminal(currentTerminal)) { return EmptyHandlerCollection; } var requiredPrecedingTerminalId = GetRequiredPrecedingTerminalId(currentTerminal); var literalTerminals = FindUsagesCommand.GetEqualValueLiteralTerminals(semanticModel.Statement, currentTerminal) .Where(t => requiredPrecedingTerminalId == t.PrecedingTerminal.Id || (requiredPrecedingTerminalId == null && !t.PrecedingTerminal.Id.In(Terminals.Date, Terminals.Timestamp))) .ToArray(); var singleOccurenceConvertAction = new CommandExecutionHandler { Name = "Convert to bind variable", ExecutionHandler = c => new LiteralBindVariableConversionCommand(c, new[] { currentTerminal }, requiredPrecedingTerminalId) .Execute(), CanExecuteHandler = c => true }; commands.Add(singleOccurenceConvertAction); if (literalTerminals.Length > 1) { var allOccurencesConvertAction = new CommandExecutionHandler { Name = "Convert all occurences to bind variable", ExecutionHandler = c => new LiteralBindVariableConversionCommand(c, literalTerminals, requiredPrecedingTerminalId) .Execute(), CanExecuteHandler = c => true }; commands.Add(allOccurencesConvertAction); } return commands.AsReadOnly(); }
public OracleQueryBlock(OracleStatement statement, StatementGrammarNode rootNode, OracleStatementSemanticModel semanticModel) : base(semanticModel) { if (rootNode == null) { throw new ArgumentNullException(nameof(rootNode)); } if (!String.Equals(rootNode.Id, NonTerminals.QueryBlock)) { throw new ArgumentException($"'rootNode' parameter must be '{NonTerminals.QueryBlock}' non-terminal. ", nameof(rootNode)); } Statement = statement; RootNode = rootNode; FromClause = rootNode[NonTerminals.FromClause]; HierarchicalQueryClause = rootNode[NonTerminals.HierarchicalQueryClause]; if (HierarchicalQueryClause != null) { var hasNoCycleSupport = HierarchicalQueryClause[NonTerminals.HierarchicalQueryConnectByClause, OracleGrammarDescription.Terminals.NoCycle] != null; HierarchicalClauseReference = new OracleHierarchicalClauseReference(hasNoCycleSupport); } }
public static ICollection<CommandExecutionHandler> ResolveCommandHandlers(OracleStatementSemanticModel semanticModel, StatementGrammarNode currentTerminal) { CheckParametersNotNull(semanticModel, currentTerminal); if (!String.Equals(currentTerminal.Id, Terminals.BindVariableIdentifier)) return EmptyHandlerCollection; var bindVariable = FindUsagesCommand.GetBindVariable(semanticModel, currentTerminal.Token.Value); var singleOccurenceConvertAction = new CommandExecutionHandler { Name = "Convert to literal", ExecutionHandler = c => new BindVariableLiteralConversionCommand(c, bindVariable, false) .Execute(), CanExecuteHandler = c => true }; var commands = new List<CommandExecutionHandler> { singleOccurenceConvertAction }; if (bindVariable.Nodes.Count > 1) { var allOccurencesConvertAction = new CommandExecutionHandler { Name = "Convert all accurences to literal", ExecutionHandler = c => new BindVariableLiteralConversionCommand(c, bindVariable, true) .Execute(), CanExecuteHandler = c => true }; commands.Add(allOccurencesConvertAction); } return commands.AsReadOnly(); }
private static IEnumerable<OracleCodeCompletionItem> CreateAsteriskColumnCompletionItems(IEnumerable<OracleObjectWithColumnsReference> tables, bool skipFirstObjectIdentifier, StatementGrammarNode nodeToReplace) { var formatOption = FormatOptions.Identifier; var builder = new StringBuilder(); foreach (var table in tables) { if (table.Columns.Count <= 1) { continue; } builder.Clear(); var skipTablePrefix = skipFirstObjectIdentifier; var separator = String.Empty; var rowSourceFullName = String.Empty; if (table.FullyQualifiedObjectName.HasOwner) { var rowSourceOwner = table.FullyQualifiedObjectName.Owner.ToSimpleIdentifier(); rowSourceFullName = $"{OracleStatementFormatter.FormatTerminalValue(rowSourceOwner, formatOption)}."; } var rowSourceName = table.FullyQualifiedObjectName.Name.ToSimpleIdentifier(); rowSourceFullName = $"{rowSourceFullName}{OracleStatementFormatter.FormatTerminalValue(rowSourceName, formatOption)}"; foreach (var column in table.Columns) { if (column.Hidden) { continue; } builder.Append(separator); if (!skipTablePrefix && !String.IsNullOrEmpty(table.FullyQualifiedObjectName.Name)) { builder.Append(rowSourceFullName); builder.Append("."); } builder.Append(OracleStatementFormatter.FormatTerminalValue(column.Name.ToSimpleIdentifier(), formatOption)); skipTablePrefix = false; separator = ", "; } yield return new OracleCodeCompletionItem { Name = (skipFirstObjectIdentifier || String.IsNullOrEmpty(table.FullyQualifiedObjectName.Name) ? String.Empty : $"{rowSourceFullName}.") + "*", Text = builder.ToString(), StatementNode = nodeToReplace, CategoryPriority = -2, Category = OracleCodeCompletionCategory.AllColumns }; } }
private static IEnumerable<ICodeCompletionItem> GenerateColumnAliases(StatementGrammarNode currentTerminal, OracleCodeCompletionType completionType) { var formatOption = FormatOptions.Identifier; return completionType.CurrentQueryBlock.Columns .Where(c => c.HasExplicitAlias) .Select(c => { var identifier = OracleStatementFormatter.FormatTerminalValue(c.NormalizedName.ToSimpleIdentifier(), formatOption); return new OracleCodeCompletionItem { Name = identifier, Text = identifier, Category = OracleCodeCompletionCategory.Column, StatementNode = currentTerminal }; }); }
private static IEnumerable<ICodeCompletionItem> GenerateCommonTableExpressionReferenceItems(OracleStatementSemanticModel model, string referenceNamePart, StatementGrammarNode node, int insertOffset) { var formatOption = FormatOptions.Alias; // TODO: Make proper resolution of CTE accessibility return model.QueryBlocks .Where(qb => qb.Type == QueryBlockType.CommonTableExpression && qb.PrecedingConcatenatedQueryBlock == null && referenceNamePart.ToQuotedIdentifier() != qb.NormalizedAlias && CodeCompletionSearchHelper.IsMatch(qb.Alias, referenceNamePart)) .Select(qb => { var alias = OracleStatementFormatter.FormatTerminalValue(qb.Alias, formatOption); return new OracleCodeCompletionItem { Name = alias, Text = alias, StatementNode = node, Category = OracleCodeCompletionCategory.CommonTableExpression, InsertOffset = insertOffset, CategoryPriority = -1 }; }); }
private static StatementGrammarNode FindCommentTargetNode(StatementGrammarNode node, int index) { while (true) { if (!node.SourcePosition.ContainsIndex(index)) { return null; } // NOTE: FirstOrDefault must be used because child nodes in invalid grammar can overlap. var candidateNode = node.ChildNodes.FirstOrDefault(n => n.SourcePosition.ContainsIndex(index)); if (candidateNode == null || candidateNode.Type == NodeType.Terminal) { return node; } node = candidateNode; } }
private static bool CanConvertCurrentTerminal(StatementGrammarNode currentTerminal) { return currentTerminal.Id.In(Terminals.NumberLiteral, Terminals.StringLiteral) && currentTerminal.RootNode[0, 0].Id.In(NonTerminals.SelectStatement, NonTerminals.UpdateStatement, NonTerminals.DeleteStatement, NonTerminals.InsertStatement, NonTerminals.MergeStatement) || currentTerminal.RootNode.Id == NonTerminals.PlSqlBlockStatement; }
private static StatementCollection ProceedGrammar(IEnumerable<OracleToken> tokens, CancellationToken cancellationToken) { var allTokens = new List<IToken>(); var tokenBuffer = new List<OracleToken>(); var commentBuffer = new List<OracleToken>(); foreach (var token in tokens) { if (token.CommentType == CommentType.None) { tokenBuffer.Add(token); } else { commentBuffer.Add(token); } allTokens.Add(token); } var oracleSqlCollection = new List<StatementBase>(); if (tokenBuffer.Count == 0) { return new OracleStatementCollection(oracleSqlCollection, allTokens, commentBuffer.Select(c => new StatementCommentNode(null, c))); } do { var result = new ParseResult(); var context = new ParseContext { CancellationToken = cancellationToken, Statement = new OracleStatement(), TokenBuffer = tokenBuffer }; foreach (var nonTerminal in AvailableNonTerminals) { var newResult = ProceedNonTerminal(context, nonTerminal, 1, 0, false, nonTerminal.TargetRule.Scope); //if (newResult.Nodes.SelectMany(n => n.AllChildNodes).Any(n => n.Terminals.Count() != n.TerminalCount)) // throw new ApplicationException("StatementGrammarNode TerminalCount value is invalid. "); if (newResult.Status != ParseStatus.Success) { if (result.BestCandidates == null || newResult.BestCandidates.Sum(n => n.TerminalCount) > result.BestCandidates.Sum(n => n.TerminalCount)) { result = newResult; } continue; } result = newResult; var lastTerminal = result.Nodes[result.Nodes.Count - 1].LastTerminalNode; if (lastTerminal == null || !TerminatorIds.Contains(lastTerminal.Id) && tokenBuffer.Count > result.Nodes.Sum(n => n.TerminalCount)) { if (lastTerminal != null) { var lastToken = result.BestCandidates.Last().LastTerminalNode.Token; var parsedTerminalCount = result.BestCandidates.Sum(n => n.TerminalCount); context.Statement.FirstUnparsedToken = tokenBuffer.Count > parsedTerminalCount ? tokenBuffer[parsedTerminalCount] : lastToken; } result.Status = ParseStatus.SequenceNotFound; } break; } int indexStart; int indexEnd; if (result.Status != ParseStatus.Success) { if (result.BestCandidates.Sum(n => n.TerminalCount) > result.Nodes.Sum(n => n.TerminalCount)) { result.Nodes = result.BestCandidates; } indexStart = tokenBuffer.First().Index; var index = tokenBuffer.FindIndex(t => TerminatorValues.Contains(t.Value)); if (index == -1) { var lastToken = tokenBuffer[tokenBuffer.Count - 1]; indexEnd = lastToken.Index + lastToken.Value.Length - 1; tokenBuffer.Clear(); } else { indexEnd = tokenBuffer[index].Index; tokenBuffer.RemoveRange(0, index + 1); } } else { var lastTerminal = result.Nodes[result.Nodes.Count - 1].LastTerminalNode.Token; indexStart = result.Nodes[0].FirstTerminalNode.Token.Index; indexEnd = lastTerminal.Index + lastTerminal.Value.Length - 1; tokenBuffer.RemoveRange(0, result.Nodes.Sum(n => n.TerminalCount)); var hasInvalidGrammarNodes = result.Nodes.Any(HasInvalidGrammarNodes); if (hasInvalidGrammarNodes) { result.Status = ParseStatus.SequenceNotFound; } } var lastNode = result.Nodes.LastOrDefault(); if (lastNode?.FirstTerminalNode != null && TerminatorIds.Contains(lastNode.FirstTerminalNode.Id)) { context.Statement.TerminatorNode = lastNode.FirstTerminalNode; result.Nodes.Remove(lastNode); } context.Statement.SourcePosition = SourcePosition.Create(indexStart, indexEnd); var rootNode = new StatementGrammarNode(NodeType.NonTerminal, context.Statement, null) { Id = result.NodeId, IsGrammarValid = result.Nodes.All(n => n.IsGrammarValid), IsRequired = true, }; rootNode.AddChildNodes(result.Nodes); context.Statement.RootNode = rootNode; context.Statement.ParseStatus = result.Status; oracleSqlCollection.Add(context.Statement); } while (tokenBuffer.Count > 0); var commentNodes = AddCommentNodes(oracleSqlCollection, commentBuffer); return new OracleStatementCollection(oracleSqlCollection, allTokens, commentNodes); }
private static IEnumerable<ICodeCompletionItem> GenerateCodeItems(string category, StatementGrammarNode node, int insertOffset, bool addParameterList, OracleDatabaseModelBase databaseModel, params OracleProgramMatcher[] matchers) { string parameterList = null; var parameterListCaretOffset = 0; if (addParameterList) { parameterList = "()"; parameterListCaretOffset = -1; } var quotedSchemaName = databaseModel.CurrentSchema.ToQuotedIdentifier(); var formatOptionIdentifier = FormatOptions.Identifier; var formatOptionReservedWord = FormatOptions.ReservedWord; return databaseModel.AllProgramMetadata .SelectMany(g => g) .SelectMany(f => matchers.Select(m => m.GetMatchResult(f, quotedSchemaName))) .Where(r => r.IsMatched) .SelectMany(r => r.Matches.Where(v => !String.IsNullOrEmpty(v)).Select(v => new { Name = v.ToSimpleIdentifier(), r.Metadata })) .GroupBy(r => r.Name) .Select(g => new { Name = g.Key, MetadataCollection = g.Select(i => i.Metadata).ToArray() }) .Select(i => { var metadata = i.MetadataCollection[0]; var hasReservedWordName = metadata.IsBuiltIn && i.Name.CollidesWithReservedWord(); var programName = i.Name; var formatOption = formatOptionIdentifier; if (hasReservedWordName) { programName = i.Name.Trim('"'); formatOption = formatOptionReservedWord; } programName = OracleStatementFormatter.FormatTerminalValue(programName, formatOption); var postFix = parameterList; var isPackage = String.Equals(category, OracleCodeCompletionCategory.Package); if (isPackage) { postFix = "."; } else if (hasReservedWordName || String.Equals(metadata.DisplayType, OracleProgramMetadata.DisplayTypeNoParenthesis)) { postFix = null; } else if (addParameterList && metadata.IsBuiltIn && Equals(metadata.Identifier, OracleProgramIdentifier.IdentifierBuiltInProgramExtract)) { postFix = "(DAY FROM )"; } var analyticClause = addParameterList ? GetAdditionalFunctionClause(i.MetadataCollection) : String.Empty; string description = null; if (metadata.Owner != null || metadata.IsBuiltIn) { description = isPackage ? metadata.Owner?.Documentation : metadata.Documentation; } return new OracleCodeCompletionItem { Name = programName, Text = $"{programName}{postFix}{analyticClause}", StatementNode = node, Category = category, InsertOffset = insertOffset, CaretOffset = hasReservedWordName || isPackage || String.Equals(metadata.DisplayType, OracleProgramMetadata.DisplayTypeNoParenthesis) ? 0 : parameterListCaretOffset - analyticClause.Length, CategoryPriority = 2, Description = description }; }); }
private static ParseResult ProceedNonTerminal(ParseContext context, SqlGrammarRuleSequenceNonTerminal nonTerminal, int level, int tokenStartOffset, bool tokenReverted, ReservedWordScope scope) { if (nonTerminal.TargetRule.Scope != ReservedWordScope.Inherit) { scope = nonTerminal.TargetRule.Scope; } var bestCandidateNodes = new List<StatementGrammarNode>(); var workingNodes = new List<StatementGrammarNode>(); var nonTerminalId = nonTerminal.Id; var result = new ParseResult { NodeId = nonTerminalId, Nodes = workingNodes, BestCandidates = bestCandidateNodes, }; var workingTerminalCount = 0; var bestCandidateTerminalCount = 0; var isPlSqlStatement = String.Equals(nonTerminalId, OracleGrammarDescription.NonTerminals.PlSqlStatementType); if (isPlSqlStatement) { context.PlSqlStatementTokenIndex.Push(tokenStartOffset); } foreach (var sequence in nonTerminal.TargetRule.Sequences) { context.CancellationToken.ThrowIfCancellationRequested(); result.Status = ParseStatus.Success; workingNodes.Clear(); workingTerminalCount = 0; var bestCandidatesCompatible = false; var isSequenceValid = true; foreach (ISqlGrammarRuleSequenceItem item in sequence.Items) { var tokenOffset = tokenStartOffset + workingTerminalCount; var isNodeRequired = item.IsRequired; if (tokenOffset >= context.TokenBuffer.Count && !isNodeRequired) { continue; } var childNodeId = item.Id; if (!isNodeRequired && workingTerminalCount == 0 && String.Equals(childNodeId, nonTerminalId)) { continue; } var bestCandidateOffset = tokenStartOffset + bestCandidateTerminalCount; var tryBestCandidates = bestCandidatesCompatible && !tokenReverted && bestCandidateTerminalCount > workingTerminalCount; var childNonTerminal = item as SqlGrammarRuleSequenceNonTerminal; if (childNonTerminal != null) { var nestedResult = ProceedNonTerminal(context, childNonTerminal, level + 1, tokenOffset, false, scope); var optionalTokenReverted = TryRevertOptionalToken(optionalTerminalCount => ProceedNonTerminal(context, childNonTerminal, level + 1, tokenOffset - optionalTerminalCount, true, scope), ref nestedResult, workingNodes); workingTerminalCount -= optionalTokenReverted; TryParseInvalidGrammar(tryBestCandidates, () => ProceedNonTerminal(context, childNonTerminal, level + 1, bestCandidateOffset, false, scope), ref nestedResult, workingNodes, bestCandidateNodes, ref workingTerminalCount); var isNestedNodeValid = nestedResult.Status == ParseStatus.Success; if (isNodeRequired || isNestedNodeValid) { result.Status = nestedResult.Status; } var nestedNode = new StatementGrammarNode(NodeType.NonTerminal, context.Statement, null) { Id = childNodeId, Level = level, IsRequired = isNodeRequired, IsGrammarValid = isNestedNodeValid }; var alternativeNode = nestedNode.Clone(); int currentTerminalCount; if (nestedResult.BestCandidates.Count > 0 && ((currentTerminalCount = workingTerminalCount + nestedResult.BestCandidateTerminalCount) > bestCandidateTerminalCount || (currentTerminalCount == bestCandidateTerminalCount && isNestedNodeValid))) { var bestCandidatePosition = new Dictionary<int, StatementGrammarNode>(); // Candidate nodes can be multiplied or terminals can be spread among different nonterminals, // therefore we fetch the node with most terminals or the later (when nodes contain same terminals). foreach (var candidate in nestedResult.BestCandidates) { StatementGrammarNode storedNode; if (!bestCandidatePosition.TryGetValue(candidate.SourcePosition.IndexStart, out storedNode) || storedNode.SourcePosition.IndexEnd <= candidate.SourcePosition.IndexEnd) { bestCandidatePosition[candidate.SourcePosition.IndexStart] = candidate; } } alternativeNode.AddChildNodes(bestCandidatePosition.Values); if (optionalTokenReverted > 0 || !isNestedNodeValid || workingNodes.Count != bestCandidateNodes.Count) { bestCandidateTerminalCount = CreateNewNodeList(workingNodes, bestCandidateNodes); } bestCandidateNodes.Add(alternativeNode); bestCandidateTerminalCount += alternativeNode.TerminalCount; bestCandidatesCompatible = true; } if (isNestedNodeValid && nestedResult.Nodes.Count > 0) { nestedNode.AddChildNodes(nestedResult.Nodes); workingNodes.Add(nestedNode); workingTerminalCount += nestedResult.TerminalCount; } if (result.Status == ParseStatus.SequenceNotFound) { if (workingNodes.Count == 0) { break; } isSequenceValid = false; workingNodes.Add(alternativeNode.Clone()); workingTerminalCount += alternativeNode.TerminalCount; } } else { var terminalReference = (SqlGrammarRuleSequenceTerminal)item; var terminalResult = IsTokenValid(context, terminalReference, level, tokenOffset, scope); TryParseInvalidGrammar(tryBestCandidates && isNodeRequired, () => IsTokenValid(context, terminalReference, level, bestCandidateOffset, scope), ref terminalResult, workingNodes, bestCandidateNodes, ref workingTerminalCount); if (terminalResult.Status == ParseStatus.SequenceNotFound) { if (isNodeRequired) { result.Status = ParseStatus.SequenceNotFound; break; } continue; } workingTerminalCount++; bestCandidateTerminalCount++; var terminalNode = terminalResult.Nodes[0]; workingNodes.Add(terminalNode); bestCandidateNodes.Add(terminalNode.Clone()); } } if (result.Status == ParseStatus.Success) { #region CASE WHEN issue if (bestCandidateTerminalCount > workingTerminalCount) { var currentTerminalCount = bestCandidateNodes.SelectMany(n => n.Terminals).TakeWhile(t => !t.Id.IsIdentifierOrAlias() && !t.Id.IsLiteral()).Count(); if (currentTerminalCount > workingTerminalCount && workingNodes.FirstOrDefault()?.FirstTerminalNode.Id.IsIdentifierOrAlias() == true) { workingNodes.ForEach(n => n.IsGrammarValid = false); } } #endregion if (isSequenceValid) { break; } } } if (isPlSqlStatement) { context.PlSqlStatementTokenIndex.Pop(); } result.BestCandidates = bestCandidateNodes; result.TerminalCount = workingTerminalCount; result.BestCandidateTerminalCount = bestCandidateTerminalCount; return result; }
private static StatementGrammarNode TryGetOptionalAncestor(StatementGrammarNode node) { while (node != null && node.IsRequired) { node = node.ParentNode; } return node; }
private static int RevertLastOptionalNode(IList<StatementGrammarNode> workingNodes, StatementGrammarNode optionalNodeCandidate) { var indexToRemove = workingNodes.Count - 1; var nodeToRemove = workingNodes[indexToRemove]; if (nodeToRemove.Type == NodeType.NonTerminal && nodeToRemove != optionalNodeCandidate) { return nodeToRemove.RemoveLastChildNodeIfOptional(); } workingNodes.RemoveAt(indexToRemove); return nodeToRemove.TerminalCount; }
private static ParseResult IsTokenValid(ParseContext context, SqlGrammarRuleSequenceTerminal terminalReference, int level, int tokenOffset, ReservedWordScope scope) { var tokenIsValid = false; IList<StatementGrammarNode> nodes = null; var terminalId = terminalReference.Id; if (context.TokenBuffer.Count > tokenOffset) { var currentToken = context.TokenBuffer[tokenOffset]; var terminal = terminalReference.Terminal; var isReservedWord = false; if (String.IsNullOrEmpty(terminal.RegexValue)) { var tokenValue = currentToken.UpperInvariantValue; tokenIsValid = String.Equals(terminal.Value, tokenValue) || (terminal.AllowQuotedNotation && tokenValue.Length == terminal.Value.Length + 2 && tokenValue[0] == '"' && tokenValue[tokenValue.Length - 1] == '"' && String.Equals(tokenValue.Substring(1, tokenValue.Length - 2), terminal.Value)); isReservedWord = tokenIsValid && (scope == ReservedWordScope.Sql ? terminal.ReservedWord == ReservedWordType.Sql : terminal.ReservedWord > 0); } else { tokenIsValid = terminal.RegexMatcher.IsMatch(currentToken.Value); if (tokenIsValid && !terminalReference.AllowReservedWord) { var isNotReservedWord = !OracleGrammarDescription.ReservedWordsSql.Contains(currentToken.UpperInvariantValue); if (isNotReservedWord && scope == ReservedWordScope.PlSqlBody) { var effectiveReservedWords = context.PlSqlStatementTokenIndex.Count == 0 || context.PlSqlStatementTokenIndex.Peek() == tokenOffset ? OracleGrammarDescription.ReservedWordsPlSqlBody : OracleGrammarDescription.ReservedWordsPlSql; isNotReservedWord = !effectiveReservedWords.Contains(currentToken.UpperInvariantValue); } if (isNotReservedWord && scope == ReservedWordScope.PlSqlDeclaration) { isNotReservedWord = !OracleGrammarDescription.ReservedWordsPlSqlDeclaration.Contains(currentToken.UpperInvariantValue); } tokenIsValid &= isNotReservedWord; } } if (tokenIsValid) { var terminalNode = new StatementGrammarNode(NodeType.Terminal, context.Statement, currentToken) { Id = terminalId, Level = level, IsRequired = terminalReference.IsRequired, IsReservedWord = isReservedWord }; nodes = new[] { terminalNode }; } } return new ParseResult { NodeId = terminalId, Status = tokenIsValid ? ParseStatus.Success : ParseStatus.SequenceNotFound, Nodes = nodes }; }
protected override void Execute() { _columnList = CurrentNode.ParentNode.ChildNodes.SingleOrDefault(n => n.Id == NonTerminals.ParenthesisEnclosedPrefixedIdentifierList); var existingColumns = _columnList?.GetDescendants(Terminals.Identifier).Select(n => n.Token.Value.ToQuotedIdentifier()) ?? Enumerable.Empty<string>(); _existingColumns = existingColumns.ToHashSet(); ConfigureSettings(); if (!ExecutionContext.SettingsProvider.GetSettings()) { return; } var segmentToReplace = GetSegmentToReplace(); if (!segmentToReplace.Equals(TextSegment.Empty)) { ExecutionContext.SegmentsToReplace.Add(segmentToReplace); } }
private static ToolTipObject BuildExpectedTokenListToolTip(StatementGrammarNode node) { var candidates = OracleSqlParser.Instance.GetTerminalCandidates(node.LastTerminalNode) .Where(c => !TerminalCandidatesToSkip.Contains(c.Id)) .ToArray(); if (candidates.Length == 0) { return null; } var candidateLabels = candidates .Select(c => c.ToString()) .Distinct() .OrderBy(l => l); var candidateList = String.Join(Environment.NewLine, candidateLabels); var stackPanel = new StackPanel(); stackPanel.Children.Add(new TextBlock(new Bold(new Run("Expecting one of the following: ")))); stackPanel.Children.Add( new TextBox { Text = candidateList, IsReadOnly = true, IsReadOnlyCaretVisible = true, Background = Brushes.Transparent, BorderThickness = new Thickness() }); return new ToolTipObject { Content = stackPanel }; }
private static ICodeCompletionItem CreateColumnCodeCompletionItem(string columnName, string objectPrefix, StatementGrammarNode nodeToReplace, string category = OracleCodeCompletionCategory.Column) { var formatOption = FormatOptions.Identifier; columnName = OracleStatementFormatter.FormatTerminalValue(columnName.ToSimpleIdentifier(), formatOption); var text = String.IsNullOrEmpty(objectPrefix) ? columnName : $"{OracleStatementFormatter.FormatTerminalValue(objectPrefix, formatOption)}.{columnName}"; return new OracleCodeCompletionItem { Name = text, Text = text, StatementNode = nodeToReplace, Category = category, CategoryPriority = -1 }; }
private static IEnumerable<ICodeCompletionItem> GenerateSchemaItems(OracleCodeCompletionType completionType, StatementGrammarNode node, int insertOffset, OracleDatabaseModelBase databaseModel, int priorityOffset = 0) { var formatOption = FormatOptions.Identifier; var schemaNamePart = completionType.TerminalValuePartUntilCaret; var currentSchema = MakeSaveQuotedIdentifier(completionType.TerminalValueUnderCursor); return databaseModel.AllSchemas.Values .Where(s => !String.Equals(s.Name, OracleObjectIdentifier.SchemaPublic) && !String.Equals(currentSchema, s.Name) && CodeCompletionSearchHelper.IsMatch(s.Name, schemaNamePart)) .Select( s => { var schemaItem = OracleStatementFormatter.FormatTerminalValue(s.Name.ToSimpleIdentifier(), formatOption); return new OracleCodeCompletionItem { Name = schemaItem, Text = schemaItem, StatementNode = node, Category = OracleCodeCompletionCategory.DatabaseSchema, InsertOffset = insertOffset, CategoryPriority = 1 + priorityOffset }; }); }
private static string GetRequiredPrecedingTerminalId(StatementGrammarNode terminal) { var precedingTerminal = terminal.PrecedingTerminal; return precedingTerminal != null && precedingTerminal.Id.In(Terminals.Date, Terminals.Timestamp) ? precedingTerminal.Id : null; }
private static StatementGrammarNode GetTerminalForCandidateLookup(StatementGrammarNode node, StatementGrammarNode sourceTerminal) { if (sourceTerminal == null) { return null; } while (true) { if (node == null) { return null; } if (!node.IsGrammarValid) { return node.LastTerminalNode == sourceTerminal ? sourceTerminal : null; } node = node.ParentNode; } }
private static IEnumerable<ICodeCompletionItem> CreateObjectItems(IEnumerable<ObjectReferenceCompletionData> objects, string objectNamePart, StatementGrammarNode node, int categoryOffset = 0, int insertOffset = 0) { var safeObjectPartQuotedIdentifier = MakeSaveQuotedIdentifier(objectNamePart); var safeTokenValueQuotedIdentifier = node == null ? null : MakeSaveQuotedIdentifier(node.Token.Value); var objectNamePartUpperInvariant = objectNamePart?.ToUpperInvariant() ?? String.Empty; return objects .Where(o => !String.Equals(safeObjectPartQuotedIdentifier, o.Identifier2) && (node == null || !String.Equals(safeTokenValueQuotedIdentifier, o.Identifier2)) && CodeCompletionSearchHelper.IsMatch(o.Identifier2, objectNamePart)) .Select(o => { var schemaObject = o.SchemaObject.GetTargetSchemaObject(); DocumentationDataDictionaryObject documentation = null; if (String.Equals(schemaObject?.Owner, OracleObjectIdentifier.SchemaSys)) { OracleHelpProvider.DataDictionaryObjectDocumentation.TryGetValue(schemaObject.FullyQualifiedName, out documentation); } var completionText = o.CompletionText; return new OracleCodeCompletionItem { Name = completionText, Text = $"{completionText}{o.TextPostFix}", Priority = String.IsNullOrEmpty(objectNamePart) || completionText.TrimStart('"').ToUpperInvariant().StartsWith(objectNamePartUpperInvariant) ? 0 : 1, StatementNode = node, Category = o.Category, InsertOffset = insertOffset, CaretOffset = o.CaretOffset, CategoryPriority = categoryOffset, Description = documentation?.Value }; }); }
private static IToolTip BuildParameterToolTip(OracleStatementSemanticModel semanticModel, StatementGrammarNode node) { Func<ProgramParameterReference, bool> parameterFilter = p => p.OptionalIdentifierTerminal == node; var programReference = semanticModel.AllReferenceContainers .SelectMany(c => c.AllReferences) .OfType<OracleProgramReferenceBase>() .SingleOrDefault(r => r.ParameterReferences != null && r.ParameterReferences.Any(parameterFilter)); if (programReference?.Metadata == null) { return null; } var parameter = programReference.ParameterReferences.Single(parameterFilter); var parameterName = parameter.OptionalIdentifierTerminal.Token.Value.ToQuotedIdentifier(); OracleProgramParameterMetadata parameterMetadata; if (!programReference.Metadata.NamedParameters.TryGetValue(parameterName, out parameterMetadata)) { return null; } var comment = String.Empty; DocumentationPackageSubProgram documentation; if (OracleHelpProvider.PackageProgramDocumentations.TryGetValue(programReference.Metadata.Identifier, out documentation)) { comment = documentation.Parameters ?.SingleOrDefault(p => String.Equals(p.Name.ToQuotedIdentifier(), parameterName)) ?.Value; } return new ToolTipView { DataContext = new ObjectDetailsModel { Title = $"{parameterMetadata.Name.ToSimpleIdentifier()}: {parameterMetadata.FullDataTypeName}", Comment = comment } }; }
private static IEnumerable<OracleCodeCompletionFunctionOverload> ResolveProgramOverloads(IEnumerable<OracleReferenceContainer> referenceContainers, StatementGrammarNode node, int cursorPosition) { var programReferenceBase = referenceContainers.SelectMany(c => ((IEnumerable<OracleProgramReferenceBase>)c.ProgramReferences).Concat(c.TypeReferences)) .Where(f => node.HasAncestor(f.ParameterListNode)) .OrderByDescending(r => r.RootNode.Level) .FirstOrDefault(); if (programReferenceBase?.Metadata == null) { return Enumerable.Empty<OracleCodeCompletionFunctionOverload>(); } var currentParameterIndex = -1; if (programReferenceBase.ParameterReferences != null) { var lookupNode = node.Type == NodeType.Terminal ? node : node.GetNearestTerminalToPosition(cursorPosition); if (lookupNode.Id == Terminals.Comma) { lookupNode = cursorPosition == lookupNode.SourcePosition.IndexStart ? lookupNode.PrecedingTerminal : lookupNode.FollowingTerminal; } else if (lookupNode.Id == Terminals.LeftParenthesis && cursorPosition > lookupNode.SourcePosition.IndexStart) { lookupNode = lookupNode.FollowingTerminal; } else if (lookupNode.Id == Terminals.RightParenthesis && cursorPosition == lookupNode.SourcePosition.IndexStart) { lookupNode = lookupNode.PrecedingTerminal; } if (lookupNode != null) { var parameterReference = programReferenceBase.ParameterReferences.FirstOrDefault(f => lookupNode.HasAncestor(f.ParameterNode, true)); currentParameterIndex = parameterReference.ParameterNode == null ? programReferenceBase.ParameterReferences.Count : programReferenceBase.ParameterReferences.ToList().IndexOf(parameterReference); } } var matchedMetadata = new List<OracleProgramMetadata>(); var typeReference = programReferenceBase as OracleTypeReference; if (typeReference == null) { var programReference = (OracleProgramReference)programReferenceBase; var metadataSource = programReference.Container.SemanticModel.DatabaseModel.AllProgramMetadata[programReference.Metadata.Identifier].ToList(); if (metadataSource.Count == 0 && programReference.Owner != null && programReference.ObjectNode == null && programReference.OwnerNode == null) { metadataSource.AddRange(programReference.Owner.AccessibleAttachedFunctions.Where(m => String.Equals(m.Identifier.Name, programReference.Metadata.Identifier.Name))); } var plSqlProgram = programReference.Container as OraclePlSqlProgram; if (plSqlProgram != null) { metadataSource.AddRange(plSqlProgram.SubPrograms.Where(p => String.Equals(p.Name, programReference.Metadata.Identifier.Name)).Select(p => p.Metadata)); } matchedMetadata.AddRange(metadataSource.Where(m => IsMetadataMatched(m, programReference, currentParameterIndex)).OrderBy(m => m.Parameters.Count)); } else { matchedMetadata.Add(typeReference.Metadata); var collectionType = typeReference.SchemaObject.GetTargetSchemaObject() as OracleTypeCollection; if (collectionType != null) { currentParameterIndex = 0; } } return matchedMetadata .Select(m => new OracleCodeCompletionFunctionOverload { ProgramReference = programReferenceBase, ProgramMetadata = m, CurrentParameterIndex = currentParameterIndex }); }
private IEnumerable<ICodeCompletionItem> GenerateSchemaDataObjectItems(OracleDatabaseModelBase databaseModel, string schemaName, string objectNamePart, StatementGrammarNode node, int categoryOffset = 0, int insertOffset = 0) { return GenerateSchemaObjectItems(databaseModel, schemaName, objectNamePart, node, IsDataObject, categoryOffset, insertOffset); }
private static bool HasInvalidGrammarNodes(StatementGrammarNode node) { return !node.IsGrammarValid || node.ChildNodes.Any(HasInvalidGrammarNodes); }
private IEnumerable<ICodeCompletionItem> GenerateSchemaObjectItems(OracleDatabaseModelBase databaseModel, string schemaName, string objectNamePart, StatementGrammarNode node, Func<OracleSchemaObject, bool> filter, int categoryOffset = 0, int insertOffset = 0) { var activeSchema = databaseModel.CurrentSchema.ToQuotedIdentifier(); var safeSchemaName = MakeSaveQuotedIdentifier(schemaName); var dataObjects = databaseModel.AllObjects.Values .Where(o => (filter == null || filter(o)) && FilterSchema(o, activeSchema, safeSchemaName)) .Select(o => new ObjectReferenceCompletionData { Identifier2 = o.Name, SchemaObject = o, Category = OracleCodeCompletionCategory.SchemaObject }); return CreateObjectItems(dataObjects, objectNamePart, node, categoryOffset, insertOffset); }
private static IToolTip BuildAsteriskToolTip(OracleQueryBlock queryBlock, StatementGrammarNode asteriskTerminal) { var asteriskColumn = queryBlock.AsteriskColumns.SingleOrDefault(c => c.RootNode.LastTerminalNode == asteriskTerminal); if (asteriskColumn == null) { return null; } var columns = queryBlock.Columns.Where(c => c.AsteriskColumn == asteriskColumn) .Select((c, i) => { var validObjectReference = c.ColumnReferences[0].ValidObjectReference; var nullable = validObjectReference.SchemaObject.GetTargetSchemaObject() is OracleView ? (bool?)null : c.ColumnDescription.Nullable; return new OracleColumnModel { Name = String.IsNullOrEmpty(c.ColumnDescription.Name) ? OracleSelectListColumn.BuildNonAliasedOutputColumnName(c.RootNode.Terminals) : c.ColumnDescription.Name, FullTypeName = c.ColumnDescription.FullTypeName, Nullable = nullable, ColumnIndex = i + 1, RowSourceName = validObjectReference?.FullyQualifiedObjectName.ToLabel() }; }).ToArray(); return columns.Length == 0 ? null : new ToolTipAsterisk { Columns = columns }; }