protected void parserParameters()

in core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java [2005:2268]


    protected void parserParameters(List<SQLParameter> parameters, SQLObject parent) {
        for (; ; ) {
            SQLParameter parameter = new SQLParameter();
            parameter.setParent(parent);

            if (parent instanceof OracleCreateTypeStatement) {
                if (lexer.identifierEquals(FnvHash.Constants.MAP)) {
                    lexer.nextToken();
                    parameter.setMap(true);
                } else if (lexer.token() == Token.ORDER) {
                    lexer.nextToken();
                    parameter.setOrder(true);
                }

                // acceptIdentifier("MEMBER");
            }

            SQLName name;
            SQLDataType dataType = null;
            if (lexer.token() == Token.CURSOR) {
                lexer.nextToken();

                dataType = new SQLDataTypeImpl();
                dataType.setName("CURSOR");

                name = this.exprParser.name();

                if (lexer.token() == Token.LPAREN) {
                    lexer.nextToken();
                    this.parserParameters(parameter.getCursorParameters(), parameter);
                    accept(Token.RPAREN);
                }

                accept(Token.IS);
                SQLSelect select = this.createSQLSelectParser().select();
                parameter.setDefaultValue(new SQLQueryExpr(select));

            } else if (lexer.token() == Token.PROCEDURE
                    || lexer.token() == Token.END
                    || lexer.token() == Token.TABLE) {
                break;
            } else if (lexer.identifierEquals(FnvHash.Constants.TYPE)) {
                lexer.nextToken();
                name = this.exprParser.name();
                accept(Token.IS);

                if (lexer.identifierEquals("REF")) {
                    lexer.nextToken();
                    accept(Token.CURSOR);

                    dataType = new SQLDataTypeImpl("REF CURSOR");
                    dataType.setDbType(dbType);
                } else if (lexer.token() == Token.TABLE) {
                    lexer.nextToken();
                    accept(Token.OF);

                    SQLName sqlName = this.exprParser.name();

                    if (lexer.token() == Token.PERCENT) {
                        lexer.nextToken();

                        String typeName;
                        if (lexer.identifierEquals(FnvHash.Constants.ROWTYPE)) {
                            lexer.nextToken();
                            typeName = "TABLE OF " + sqlName.toString() + "%ROWTYPE";
                        } else {
                            acceptIdentifier("TYPE");
                            typeName = "TABLE OF " + sqlName.toString() + "%TYPE";
                        }

                        dataType = new SQLDataTypeImpl(typeName);
                    } else if (lexer.token() == Token.LPAREN) {
                        lexer.nextToken();
                        String typeName = "TABLE OF " + sqlName.toString();

                        SQLIntegerExpr lenExpr = (SQLIntegerExpr) this.exprParser.expr();
                        int len = lenExpr.getNumber().intValue();
                        dataType = new SQLDataTypeImpl(typeName, len);
                        accept(Token.RPAREN);
                    } else {
                        String typeName = "TABLE OF " + sqlName.toString();
                        dataType = new SQLDataTypeImpl(typeName);
                    }

                    if (lexer.token() == Token.INDEX) {
                        lexer.nextToken();
                        accept(Token.BY);
                        SQLExpr indexBy = this.exprParser.primary();
                        ((SQLDataTypeImpl) dataType).setIndexBy(indexBy);
                    }
                    dataType.setDbType(dbType);
                } else if (lexer.identifierEquals("VARRAY")) {
                    lexer.nextToken();
                    accept(Token.LPAREN);
                    int len = this.exprParser.acceptInteger();
                    accept(Token.RPAREN);
                    accept(Token.OF);

                    if (lexer.identifierEquals("NUMBER")) {
                        lexer.nextToken();
                        String typeName = "VARRAY(" + len + ") OF NUMBER";

                        if (lexer.token() == Token.LPAREN) {
                            accept(Token.LPAREN);
                            int numLen = this.exprParser.acceptInteger();
                            accept(Token.RPAREN);
                            typeName += "(" + numLen + ")";
                        }
                        dataType = new SQLDataTypeImpl(typeName);
                        dataType.setDbType(dbType);
                    } else if (lexer.identifierEquals("VARCHAR2")) {
                        lexer.nextToken();
                        String typeName = "VARRAY(" + len + ") OF VARCHAR2";
                        dataType = new SQLDataTypeImpl(typeName);
                        dataType.setDbType(dbType);

                        if (lexer.token() == Token.LPAREN) {
                            lexer.nextToken();
                            this.exprParser.exprList(dataType.getArguments(), dataType);
                            accept(Token.RPAREN);
                        }
                    } else {
                        throw new ParserException("TODO : " + lexer.info());
                    }
                } else {
                    throw new ParserException("TODO : " + lexer.info());
                }
            } else {
                if (lexer.token() == Token.KEY) {
                    name = new SQLIdentifierExpr(lexer.stringVal());
                    lexer.nextToken();
                } else if (lexer.identifierEquals("ENUM")) {
                    name = this.exprParser.name();
                    SQLListExpr enumList = (SQLListExpr) this.exprParser.expr();
                    parameter.setName(name);
                    dataType = new SQLDataTypeImpl("ENUM", enumList);
                    parameter.setDataType(dataType);
                    parameters.add(parameter);
                    break;
                } else {
                    name = this.exprParser.name();
                }

                if (lexer.token() == Token.IN) {
                    lexer.nextToken();

                    if (lexer.token() == Token.OUT) {
                        lexer.nextToken();
                        parameter.setParamType(SQLParameter.ParameterType.INOUT);
                    } else {
                        parameter.setParamType(SQLParameter.ParameterType.IN);
                    }
                } else if (lexer.token() == Token.OUT) {
                    lexer.nextToken();

                    if (lexer.token() == Token.IN) {
                        lexer.nextToken();
                        parameter.setParamType(SQLParameter.ParameterType.INOUT);
                    } else {
                        parameter.setParamType(SQLParameter.ParameterType.OUT);
                    }
                } else if (lexer.token() == Token.INOUT) {
                    lexer.nextToken();
                    parameter.setParamType(SQLParameter.ParameterType.INOUT);
                }

                if (lexer.identifierEquals("NOCOPY")) {
                    lexer.nextToken();
                    parameter.setNoCopy(true);
                }

                if (lexer.identifierEquals("CONSTANT")) {
                    lexer.nextToken();
                    parameter.setConstant(true);
                }

                if ((name.nameHashCode64() == FnvHash.Constants.MEMBER
                        || name.nameHashCode64() == FnvHash.Constants.STATIC)
                        && lexer.token() == Token.FUNCTION) {
                    if (name.nameHashCode64() == FnvHash.Constants.MEMBER) {
                        parameter.setMember(true);
                    }
                    OracleFunctionDataType functionDataType = new OracleFunctionDataType();
                    functionDataType.setStatic(name.nameHashCode64() == FnvHash.Constants.STATIC);
                    lexer.nextToken();
                    functionDataType.setName(lexer.stringVal());
                    accept(Token.IDENTIFIER);
                    if (lexer.token() == Token.LPAREN) {
                        lexer.nextToken();
                        this.parserParameters(functionDataType.getParameters(), functionDataType);
                        accept(Token.RPAREN);
                    }
                    accept(Token.RETURN);
                    functionDataType.setReturnDataType(this.exprParser.parseDataType(false));
                    dataType = functionDataType;
                    name = null;

                    if (lexer.token() == Token.IS) {
                        lexer.nextToken();
                        SQLStatement block = this.parseBlock();
                        functionDataType.setBlock(block);
                    }
                } else if ((name.nameHashCode64() == FnvHash.Constants.MEMBER
                        || name.nameHashCode64() == FnvHash.Constants.STATIC)
                        && lexer.token() == Token.PROCEDURE) {
                    if (name.nameHashCode64() == FnvHash.Constants.MEMBER) {
                        parameter.setMember(true);
                    }
                    OracleProcedureDataType procedureDataType = new OracleProcedureDataType();
                    procedureDataType.setStatic(name.nameHashCode64() == FnvHash.Constants.STATIC);
                    lexer.nextToken();
                    procedureDataType.setName(lexer.stringVal());
                    accept(Token.IDENTIFIER);
                    if (lexer.token() == Token.LPAREN) {
                        lexer.nextToken();
                        this.parserParameters(procedureDataType.getParameters(), procedureDataType);
                        accept(Token.RPAREN);
                    }

                    dataType = procedureDataType;
                    name = null;

                    if (lexer.token() == Token.IS) {
                        lexer.nextToken();
                        SQLStatement block = this.parseBlock();
                        procedureDataType.setBlock(block);
                    }
                } else {
                    dataType = this.exprParser.parseDataType(false);
                }

                if (lexer.token() == Token.NOT) {
                    lexer.nextToken();
                    accept(Token.NULL);
                    parameter.setNotNull(true);
                }

                if (lexer.token() == Token.COLONEQ || lexer.token() == Token.DEFAULT) {
                    lexer.nextToken();
                    parameter.setDefaultValue(this.exprParser.expr());
                }
            }

            parameter.setName(name);
            parameter.setDataType(dataType);

            parameters.add(parameter);
            Token token = lexer.token();
            if (token == Token.COMMA || token == Token.SEMI || token == Token.IS) {
                lexer.nextToken();
            }

            token = lexer.token();
            if (token != Token.BEGIN
                    && token != Token.RPAREN
                    && token != Token.EOF
                    && token != Token.FUNCTION
                    && !lexer.identifierEquals("DETERMINISTIC")) {
                continue;
            }

            break;
        }
    }