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 void ResolvePlSqlReferences(OraclePlSqlProgram program) { ResolveProgramReferences(program.ProgramReferences, true); foreach (var variableReference in program.PlSqlVariableReferences.Concat(program.SqlModels.SelectMany(m => m.AllReferenceContainers).SelectMany(c => c.PlSqlVariableReferences))) { TryResolveLocalReference(variableReference, program.AccessibleVariables, variableReference.Variables); } var sourceColumnReferences = program.ColumnReferences .Concat( program.SqlModels .SelectMany(m => m.AllReferenceContainers) .SelectMany(c => c.ColumnReferences) .Where(c => !c.ReferencesAllColumns && c.ColumnNodeColumnReferences.Count == 0 && c.ObjectNodeObjectReferences.Count == 0)) .ToArray(); foreach (var columnReference in sourceColumnReferences) { var variableReference = new OraclePlSqlVariableReference { PlSqlProgram = program, IdentifierNode = columnReference.ColumnNode }; variableReference.CopyPropertiesFrom(columnReference); var elementSource = variableReference.PlSqlProgram.AccessibleVariables.Concat(variableReference.PlSqlProgram.Parameters); var variableResolved = TryResolveLocalReference(variableReference, elementSource, variableReference.Variables); if (variableResolved) { columnReference.Container.ColumnReferences.Remove(columnReference); } else { variableResolved = !TryColumnReferenceAsProgramOrSequenceReference(columnReference, true); } if (variableResolved && !IsBooleanLiteral(columnReference)) { program.PlSqlVariableReferences.Add(variableReference); } } program.ColumnReferences.Clear(); foreach (var exceptionReference in program.PlSqlExceptionReferences) { TryResolveLocalReference(exceptionReference, program.Exceptions, exceptionReference.Exceptions); } foreach (var dataTypeReference in program.DataTypeReferences) { OracleReferenceBuilder.ResolveSchemaType(dataTypeReference); } ResolveSubProgramReferences(program.SubPrograms); }
private void FindPlSqlReferences(IEnumerable <OraclePlSqlProgram> programs) { foreach (var program in programs) { var declarationReferenceSourceNodes = program.RootNode.GetPathFilterDescendants(n => !String.Equals(n.Id, NonTerminals.ItemList2) && !String.Equals(n.Id, NonTerminals.ProgramBody) && !String.Equals(n.Id, NonTerminals.CursorDefinition), NonTerminals.PlSqlExpression, NonTerminals.PlSqlDataType); foreach (var sourceNode in declarationReferenceSourceNodes) { switch (sourceNode.Id) { case NonTerminals.PlSqlExpression: FindPlSqlReferences(program, sourceNode); break; case NonTerminals.PlSqlDataType: OracleDataTypeReference dataTypeReference; OracleReferenceBuilder.TryCreatePlSqlDataTypeReference(program, sourceNode, out dataTypeReference); break; } } var programBodyNode = program.RootNode.GetPathFilterDescendants(n => !String.Equals(n.Id, NonTerminals.ProgramDeclareSection), NonTerminals.ProgramBody).FirstOrDefault(); if (programBodyNode != null) { foreach (var statementTypeNode in GetPlSqlStatements(programBodyNode)) { FindPlSqlReferences(program, statementTypeNode[0]); } var exceptionHandlerListNode = programBodyNode[NonTerminals.PlSqlExceptionClause, NonTerminals.PlSqlExceptionHandlerList]; if (exceptionHandlerListNode != null) { foreach (var prefixedExceptionIdentifierNode in exceptionHandlerListNode.GetPathFilterDescendants(NodeFilters.BreakAtPlSqlSubProgramOrSqlCommand, NonTerminals.PrefixedExceptionIdentifier)) { CreatePlSqlExceptionReference(program, prefixedExceptionIdentifierNode); } var exceptionHandlerStatementLists = StatementGrammarNode.GetAllChainedClausesByPath(exceptionHandlerListNode[NonTerminals.PlSqlExceptionHandler, NonTerminals.PlSqlStatementList], null, NonTerminals.PlSqlExceptionHandlerList, NonTerminals.PlSqlExceptionHandler, NonTerminals.PlSqlStatementList); foreach (var statementList in exceptionHandlerStatementLists) { foreach (var statementTypeNode in GetPlSqlStatements(statementList)) { FindPlSqlReferences(program, statementTypeNode[0]); } } } } FindPlSqlReferences(program.SubPrograms); } }
private void ResolveLocalVariableTypeAndLabelDeclarations(OraclePlSqlProgram program) { StatementGrammarNode programSourceNode; switch (program.RootNode.Id) { case NonTerminals.CreateFunction: programSourceNode = program.RootNode[NonTerminals.PlSqlFunctionSource, NonTerminals.FunctionTypeDefinition, NonTerminals.ProgramImplentationDeclaration]; break; case NonTerminals.PlSqlBlock: programSourceNode = program.RootNode[NonTerminals.PlSqlBlockDeclareSection]; break; case NonTerminals.CreatePackageBody: programSourceNode = program.RootNode[NonTerminals.PackageBodyDefinition]; break; default: programSourceNode = program.RootNode[NonTerminals.ProgramImplentationDeclaration]; break; } ResolveProgramDeclarationLabels(program); var firstItemNode = programSourceNode?[NonTerminals.ProgramDeclareSection, NonTerminals.ItemList1, NonTerminals.Item1OrPragmaDefinition]; if (firstItemNode == null) { return; } var itemOrPragmaNodes = StatementGrammarNode.GetAllChainedClausesByPath(firstItemNode, n => n.ParentNode, NonTerminals.ItemList1Chained, NonTerminals.Item1OrPragmaDefinition); foreach (var itemOrPragmaSwitchNode in itemOrPragmaNodes) { var itemOrPragmaNode = itemOrPragmaSwitchNode[0]; if (String.Equals(itemOrPragmaNode.Id, NonTerminals.Item1)) { var declarationRoot = itemOrPragmaNode[0]; switch (declarationRoot?.Id) { case NonTerminals.ItemDeclaration: var specificNode = declarationRoot[0]; if (specificNode != null) { OraclePlSqlVariable variable; switch (specificNode.Id) { case NonTerminals.ConstantDeclaration: variable = new OraclePlSqlVariable { Owner = program, DefinitionNode = specificNode, IsConstant = true, DefaultExpressionNode = specificNode[NonTerminals.PlSqlExpression] }; SetDataTypeAndNullablePropertiesAndAddIfIdentifierFound(variable, specificNode, program); break; case NonTerminals.ExceptionDeclaration: var exceptionName = specificNode[Terminals.ExceptionIdentifier]?.Token.Value.ToQuotedIdentifier(); if (exceptionName != null) { var exception = new OraclePlSqlException { Owner = program, Name = exceptionName, DefinitionNode = specificNode }; program.Exceptions.Add(exception); } break; case NonTerminals.VariableDeclaration: specificNode = specificNode[NonTerminals.FieldDefinition]; if (specificNode != null) { variable = new OraclePlSqlVariable { Owner = program, DefinitionNode = specificNode, DefaultExpressionNode = specificNode[NonTerminals.VariableDeclarationDefaultValue, NonTerminals.PlSqlExpression], }; SetDataTypeAndNullablePropertiesAndAddIfIdentifierFound(variable, specificNode, program); } break; } } break; case NonTerminals.TypeDefinition: var typeIdentifierNode = declarationRoot[Terminals.TypeIdentifier]; var associativeArrayTypeDefinitionNode = declarationRoot[NonTerminals.TypeDefinitionSpecification, NonTerminals.CollectionTypeDefinition, NonTerminals.AssociativeArrayTypeDefinition]; if (typeIdentifierNode != null) { var type = new OraclePlSqlType { Owner = program, DefinitionNode = declarationRoot, Name = typeIdentifierNode.Token.Value.ToQuotedIdentifier(), IsAssociativeArray = associativeArrayTypeDefinitionNode?[Terminals.Index] != null }; program.Types.Add(type); var associativeArrayIndexTypeNode = associativeArrayTypeDefinitionNode?[NonTerminals.AssociativeArrayIndexType]; if (associativeArrayIndexTypeNode != null && OracleReferenceBuilder.TryCreatePlSqlDataTypeReference(program, associativeArrayIndexTypeNode, out var dataTypeReference)) { type.AssociativeArrayIndexDataTypeReference = dataTypeReference; } } break; case NonTerminals.CursorDefinition: var identifierNode = declarationRoot[Terminals.CursorIdentifier]; if (identifierNode != null) { var cursor = new OraclePlSqlCursorVariable { Owner = program, DefinitionNode = declarationRoot, Name = identifierNode.Token.Value.ToQuotedIdentifier() }; SetStatementModelIfFound(cursor, declarationRoot[NonTerminals.SelectStatement]); program.Variables.Add(cursor); } break; } } else { var exceptionInit = itemOrPragmaNode[NonTerminals.PragmaType, Terminals.ExceptionInit]; if (exceptionInit != null) { var exceptionIdentifier = exceptionInit.ParentNode[Terminals.ExceptionIdentifier]; var errorCodeModifier = exceptionInit.ParentNode[Terminals.MathMinus] == null ? 1 : -1; var integerLiteral = exceptionInit.ParentNode[Terminals.IntegerLiteral]; if (exceptionIdentifier != null && integerLiteral != null && Int32.TryParse(integerLiteral.Token.Value, out var errorCode)) { var exceptionName = exceptionIdentifier.Token.Value.ToQuotedIdentifier(); foreach (var exception in program.Exceptions) { if (String.Equals(exception.Name, exceptionName)) { exception.ErrorCode = errorCodeModifier * errorCode; } } CreatePlSqlExceptionReference(program, integerLiteral.ParentNode); } } } } }