Search in sources :

Example 1 with AbstractPgFunction

use of cz.startnet.utils.pgdiff.schema.AbstractPgFunction in project pgcodekeeper by pgcodekeeper.

the class FunctionsReader method fillFunction.

private void fillFunction(AbstractPgFunction function, ResultSet res, PgDatabase db, List<Pair<String, GenericColumn>> argsQualTypes) throws SQLException {
    function.setLanguageCost(res.getString("lang_name"), res.getFloat("procost"));
    // since 9.5 PostgreSQL
    if (SupportedVersion.VERSION_9_5.isLE(loader.version)) {
        Long[] protrftypes = getColArray(res, "protrftypes");
        if (protrftypes != null) {
            for (Long s : protrftypes) {
                function.addTransform(loader.cachedTypesByOid.get(s).getFullName());
            }
        }
    }
    if (SupportedVersion.VERSION_12.isLE(loader.version)) {
        String supportFunc = res.getString("support_func");
        if (!"-".equals(supportFunc)) {
            setFunctionWithDep(AbstractPgFunction::setSupportFunc, function, supportFunc);
        }
    }
    function.setWindow(res.getBoolean("proiswindow"));
    // VOLATILE is default
    switch(res.getString("provolatile")) {
        case "i":
            function.setVolatileType("IMMUTABLE");
            break;
        case "s":
            function.setVolatileType("STABLE");
            break;
        default:
            break;
    }
    function.setStrict(res.getBoolean("proisstrict"));
    function.setSecurityDefiner(res.getBoolean("prosecdef"));
    function.setLeakproof(res.getBoolean("proleakproof"));
    // parallel mode: s - safe, r - restricted, u - unsafe
    if (SupportedVersion.VERSION_9_6.isLE(loader.version)) {
        String parMode = res.getString("proparallel");
        switch(parMode) {
            case "s":
                function.setParallel("SAFE");
                break;
            case "r":
                function.setParallel("RESTRICTED");
                break;
            default:
                break;
        }
    }
    float rows = res.getFloat("prorows");
    if (0.0f != rows) {
        function.setRows(rows);
    }
    String[] proconfig = getColArray(res, "proconfig");
    if (proconfig != null) {
        for (String param : proconfig) {
            int eq = param.indexOf('=');
            final String par = param.substring(0, eq);
            String val = param.substring(eq + 1);
            switch(par) {
                case "temp_tablespaces":
                case "session_preload_libraries":
                case "shared_preload_libraries":
                case "local_preload_libraries":
                case "search_path":
                    function.addConfiguration(par, null);
                    loader.submitAntlrTask(val, SQLParser::vex_eof, ctx -> {
                        StringBuilder sb = new StringBuilder();
                        for (VexContext vex : ctx.vex()) {
                            sb.append(PgDiffUtils.quoteString(vex.getText()));
                            sb.append(", ");
                        }
                        sb.setLength(sb.length() - 2);
                        function.addConfiguration(par, sb.toString());
                    });
                    break;
                default:
                    val = PgDiffUtils.quoteString(val);
                    function.addConfiguration(PgDiffUtils.getQuotedName(par), val);
                    break;
            }
        }
    }
    String body = "";
    String definition = res.getString("prosrc");
    String probin = res.getString("probin");
    if (probin != null && !probin.isEmpty()) {
        StringBuilder sb = new StringBuilder();
        sb.append(PgDiffUtils.quoteString(probin));
        if (!"-".equals(definition)) {
            sb.append(", ");
            if (!definition.contains("\'") && !definition.contains("\\")) {
                sb.append(PgDiffUtils.quoteString(definition));
            } else {
                sb.append(PgDiffUtils.quoteStringDollar(definition));
            }
        }
        body = sb.toString();
    } else if (definition != null && !definition.isEmpty() && !"-".equals(definition)) {
        body = PgDiffUtils.quoteStringDollar(definition);
    } else if (SupportedVersion.VERSION_14.isLE(loader.version)) {
        String probody = res.getString("prosqlbody");
        // must not be null at this point, otherwise function has no body (?)
        checkObjectValidity(probody, DbObjType.FUNCTION, function.getBareName());
        function.setInStatementBody(true);
        body = probody;
    }
    function.setBody(loader.args, body);
    // Parsing the function definition and adding its result context for analysis.
    if (function.isInStatementBody()) {
        loader.submitAntlrTask(body, SQLParser::function_body, ctx -> db.addAnalysisLauncher(new FuncProcAnalysisLauncher(function, ctx, loader.getCurrentLocation(), argsQualTypes)));
    } else if (!"-".equals(definition) && "SQL".equalsIgnoreCase(function.getLanguage())) {
        loader.submitAntlrTask(definition, SQLParser::sql, ctx -> db.addAnalysisLauncher(new FuncProcAnalysisLauncher(function, ctx, loader.getCurrentLocation(), argsQualTypes)));
    } else if (!"-".equals(definition) && "PLPGSQL".equalsIgnoreCase(function.getLanguage())) {
        loader.submitPlpgsqlTask(definition, SQLParser::plpgsql_function, ctx -> db.addAnalysisLauncher(new FuncProcAnalysisLauncher(function, ctx, loader.getCurrentLocation(), argsQualTypes)));
    }
}
Also used : PgProcedure(cz.startnet.utils.pgdiff.schema.PgProcedure) ArgMode(cz.startnet.utils.pgdiff.schema.ArgMode) ListIterator(java.util.ListIterator) ApgdiffConsts(ru.taximaxim.codekeeper.apgdiff.ApgdiffConsts) ArrayList(java.util.ArrayList) SQLException(java.sql.SQLException) AbstractFunction(cz.startnet.utils.pgdiff.schema.AbstractFunction) ResultSet(java.sql.ResultSet) DbObjType(ru.taximaxim.codekeeper.apgdiff.model.difftree.DbObjType) VexContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.VexContext) GenericColumn(cz.startnet.utils.pgdiff.schema.GenericColumn) PgDatabase(cz.startnet.utils.pgdiff.schema.PgDatabase) AggKinds(cz.startnet.utils.pgdiff.schema.PgAggregate.AggKinds) JdbcQueries(cz.startnet.utils.pgdiff.loader.JdbcQueries) ModifyType(cz.startnet.utils.pgdiff.schema.PgAggregate.ModifyType) AbstractPgFunction(cz.startnet.utils.pgdiff.schema.AbstractPgFunction) PgFunction(cz.startnet.utils.pgdiff.schema.PgFunction) PgDiffUtils(cz.startnet.utils.pgdiff.PgDiffUtils) FuncProcAnalysisLauncher(cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.FuncProcAnalysisLauncher) SupportedVersion(cz.startnet.utils.pgdiff.loader.SupportedVersion) ParserAbstract(cz.startnet.utils.pgdiff.parsers.antlr.statements.ParserAbstract) AggFuncs(cz.startnet.utils.pgdiff.schema.PgAggregate.AggFuncs) List(java.util.List) AbstractSchema(cz.startnet.utils.pgdiff.schema.AbstractSchema) CreateAggregate(cz.startnet.utils.pgdiff.parsers.antlr.statements.CreateAggregate) Pair(ru.taximaxim.codekeeper.apgdiff.utils.Pair) SQLParser(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser) PgAggregate(cz.startnet.utils.pgdiff.schema.PgAggregate) Argument(cz.startnet.utils.pgdiff.schema.Argument) VexAnalysisLauncher(cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.VexAnalysisLauncher) FuncProcAnalysisLauncher(cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.FuncProcAnalysisLauncher) SQLParser(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser) AbstractPgFunction(cz.startnet.utils.pgdiff.schema.AbstractPgFunction) VexContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.VexContext)

Example 2 with AbstractPgFunction

use of cz.startnet.utils.pgdiff.schema.AbstractPgFunction in project pgcodekeeper by pgcodekeeper.

the class FunctionsReader method getFunc.

private AbstractFunction getFunc(ResultSet res, AbstractSchema schema, String funcName) throws SQLException {
    boolean isProc = SupportedVersion.VERSION_11.isLE(loader.version) && (res.getBoolean("proisproc"));
    loader.setCurrentObject(new GenericColumn(schema.getName(), funcName, isProc ? DbObjType.PROCEDURE : DbObjType.FUNCTION));
    AbstractPgFunction f = isProc ? new PgProcedure(funcName) : new PgFunction(funcName);
    PgDatabase db = schema.getDatabase();
    fillFunction(f, res, db, fillArguments(f, res));
    String defaultValuesAsString = res.getString("default_values_as_string");
    if (defaultValuesAsString != null) {
        loader.submitAntlrTask(defaultValuesAsString, SQLParser::vex_eof, ctx -> {
            List<VexContext> vexCtxList = ctx.vex();
            ListIterator<VexContext> vexCtxListIterator = vexCtxList.listIterator(vexCtxList.size());
            for (int i = (f.getArguments().size() - 1); i >= 0; i--) {
                if (!vexCtxListIterator.hasPrevious()) {
                    break;
                }
                Argument a = f.getArguments().get(i);
                if (a.getMode().isIn()) {
                    VexContext vx = vexCtxListIterator.previous();
                    a.setDefaultExpression(ParserAbstract.getFullCtxText(vx));
                    db.addAnalysisLauncher(new VexAnalysisLauncher(f, vx, loader.getCurrentLocation()));
                }
            }
        });
    }
    return f;
}
Also used : GenericColumn(cz.startnet.utils.pgdiff.schema.GenericColumn) Argument(cz.startnet.utils.pgdiff.schema.Argument) AbstractPgFunction(cz.startnet.utils.pgdiff.schema.AbstractPgFunction) PgFunction(cz.startnet.utils.pgdiff.schema.PgFunction) PgDatabase(cz.startnet.utils.pgdiff.schema.PgDatabase) VexContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.VexContext) PgProcedure(cz.startnet.utils.pgdiff.schema.PgProcedure) VexAnalysisLauncher(cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.VexAnalysisLauncher) SQLParser(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser) AbstractPgFunction(cz.startnet.utils.pgdiff.schema.AbstractPgFunction)

Example 3 with AbstractPgFunction

use of cz.startnet.utils.pgdiff.schema.AbstractPgFunction in project pgcodekeeper by pgcodekeeper.

the class CreateFunction method parseObject.

@Override
public void parseObject() {
    List<IdentifierContext> ids = ctx.function_parameters().schema_qualified_name().identifier();
    String name = QNameParser.getFirstName(ids);
    AbstractPgFunction function = ctx.PROCEDURE() != null ? new PgProcedure(name) : new PgFunction(name);
    fillFunction(function);
    if (ctx.ret_table != null) {
        function.setReturns(getFullCtxText(ctx.ret_table));
        for (Function_column_name_typeContext ret_col : ctx.ret_table.function_column_name_type()) {
            addPgTypeDepcy(ret_col.data_type(), function);
            function.addReturnsColumn(ret_col.identifier().getText(), getTypeName(ret_col.data_type()));
        }
    } else if (ctx.rettype_data != null) {
        function.setReturns(getTypeName(ctx.rettype_data));
        addPgTypeDepcy(ctx.rettype_data, function);
    }
    addSafe(getSchemaSafe(ids), function, ids, parseArguments(ctx.function_parameters().function_args()));
}
Also used : PgProcedure(cz.startnet.utils.pgdiff.schema.PgProcedure) AbstractPgFunction(cz.startnet.utils.pgdiff.schema.AbstractPgFunction) AbstractPgFunction(cz.startnet.utils.pgdiff.schema.AbstractPgFunction) PgFunction(cz.startnet.utils.pgdiff.schema.PgFunction) IdentifierContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.IdentifierContext) Function_column_name_typeContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Function_column_name_typeContext)

Example 4 with AbstractPgFunction

use of cz.startnet.utils.pgdiff.schema.AbstractPgFunction in project pgcodekeeper by pgcodekeeper.

the class CreateFunction method analyzeFunctionDefinition.

private void analyzeFunctionDefinition(AbstractPgFunction function, String language, Character_stringContext definition, List<Pair<String, GenericColumn>> funcArgs) {
    Pair<String, Token> pair = unquoteQuotedString(definition);
    String def = pair.getFirst();
    Token start = pair.getSecond();
    // Parsing the function definition and adding its result context for analysis.
    // Adding contexts of function arguments for analysis.
    String name = "function definition of " + function.getBareName();
    List<Object> err = new ArrayList<>();
    if ("SQL".equalsIgnoreCase(language)) {
        AntlrParser.submitAntlrTask(antlrTasks, () -> AntlrParser.makeBasicParser(SQLParser.class, def, name, err, start).sql(), ctx -> {
            errors.addAll(err);
            FuncProcAnalysisLauncher launcher = new FuncProcAnalysisLauncher(function, ctx, fileName, funcArgs);
            launcher.setOffset(start);
            db.addAnalysisLauncher(launcher);
        });
    } else if ("PLPGSQL".equalsIgnoreCase(language)) {
        AntlrParser.submitAntlrTask(antlrTasks, () -> {
            SQLParser parser = AntlrParser.makeBasicParser(SQLParser.class, def, name, err, start);
            AntlrUtils.removeIntoStatements(parser);
            return parser.plpgsql_function();
        }, ctx -> {
            errors.addAll(err);
            FuncProcAnalysisLauncher launcher = new FuncProcAnalysisLauncher(function, ctx, fileName, funcArgs);
            launcher.setOffset(start);
            db.addAnalysisLauncher(launcher);
        });
    }
}
Also used : IdentifierContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.IdentifierContext) PgProcedure(cz.startnet.utils.pgdiff.schema.PgProcedure) QNameParser(cz.startnet.utils.pgdiff.parsers.antlr.QNameParser) Data_typeContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Data_typeContext) Token(org.antlr.v4.runtime.Token) Character_stringContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Character_stringContext) Set_statement_valueContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Set_statement_valueContext) ApgdiffConsts(ru.taximaxim.codekeeper.apgdiff.ApgdiffConsts) ArrayList(java.util.ArrayList) AntlrParser(cz.startnet.utils.pgdiff.parsers.antlr.AntlrParser) Function_argumentsContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Function_argumentsContext) Storage_parameter_optionContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Storage_parameter_optionContext) DbObjType(ru.taximaxim.codekeeper.apgdiff.model.difftree.DbObjType) VexContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.VexContext) AntlrUtils(cz.startnet.utils.pgdiff.parsers.antlr.AntlrUtils) Function_actions_commonContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Function_actions_commonContext) GenericColumn(cz.startnet.utils.pgdiff.schema.GenericColumn) AntlrTask(cz.startnet.utils.pgdiff.parsers.antlr.AntlrTask) PgDatabase(cz.startnet.utils.pgdiff.schema.PgDatabase) Function_column_name_typeContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Function_column_name_typeContext) Transform_for_typeContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Transform_for_typeContext) With_storage_parameterContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.With_storage_parameterContext) AbstractPgFunction(cz.startnet.utils.pgdiff.schema.AbstractPgFunction) PgFunction(cz.startnet.utils.pgdiff.schema.PgFunction) PgDiffUtils(cz.startnet.utils.pgdiff.PgDiffUtils) Function_bodyContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Function_bodyContext) FuncProcAnalysisLauncher(cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.FuncProcAnalysisLauncher) List(java.util.List) Pair(ru.taximaxim.codekeeper.apgdiff.utils.Pair) SQLParser(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser) Function_defContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Function_defContext) Queue(java.util.Queue) Schema_qualified_name_nontypeContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Schema_qualified_name_nontypeContext) Argument(cz.startnet.utils.pgdiff.schema.Argument) Identifier_nontypeContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Identifier_nontypeContext) Create_function_statementContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Create_function_statementContext) VexAnalysisLauncher(cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.VexAnalysisLauncher) FuncProcAnalysisLauncher(cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.FuncProcAnalysisLauncher) SQLParser(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser) ArrayList(java.util.ArrayList) Token(org.antlr.v4.runtime.Token)

Example 5 with AbstractPgFunction

use of cz.startnet.utils.pgdiff.schema.AbstractPgFunction in project pgcodekeeper by pgcodekeeper.

the class GrantPrivilege method parseFunction.

private void parseFunction(Rule_member_objectContext obj, String permissions, List<String> roles) {
    for (Function_parametersContext funct : obj.func_name) {
        List<IdentifierContext> funcIds = funct.schema_qualified_name().identifier();
        IdentifierContext functNameCtx = QNameParser.getFirstNameCtx(funcIds);
        AbstractSchema schema = getSchemaSafe(funcIds);
        AbstractPgFunction func = (AbstractPgFunction) getSafe(AbstractSchema::getFunction, schema, parseSignature(functNameCtx.getText(), funct.function_args()), functNameCtx.getStart());
        StringBuilder sb = new StringBuilder();
        DbObjType type = obj.PROCEDURE() == null ? DbObjType.FUNCTION : DbObjType.PROCEDURE;
        addObjReference(funcIds, type, state, parseArguments(funct.function_args()));
        if (isRefMode()) {
            continue;
        }
        sb.append(type).append(' ');
        sb.append(PgDiffUtils.getQuotedName(schema.getName())).append('.');
        // For AGGREGATEs in GRANT/REVOKE the signature will be the same as in FUNCTIONs;
        // important: asterisk (*) and 'ORDER BY' are not displayed.
        func.appendFunctionSignature(sb, false, true);
        for (String role : roles) {
            addPrivilege(func, new PgPrivilege(state, permissions, sb.toString(), role, isGO));
        }
    }
}
Also used : AbstractSchema(cz.startnet.utils.pgdiff.schema.AbstractSchema) AbstractPgFunction(cz.startnet.utils.pgdiff.schema.AbstractPgFunction) DbObjType(ru.taximaxim.codekeeper.apgdiff.model.difftree.DbObjType) PgPrivilege(cz.startnet.utils.pgdiff.schema.PgPrivilege) Function_parametersContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Function_parametersContext) IdentifierContext(cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.IdentifierContext)

Aggregations

AbstractPgFunction (cz.startnet.utils.pgdiff.schema.AbstractPgFunction)7 PgFunction (cz.startnet.utils.pgdiff.schema.PgFunction)5 PgProcedure (cz.startnet.utils.pgdiff.schema.PgProcedure)4 SQLParser (cz.startnet.utils.pgdiff.parsers.antlr.SQLParser)3 IdentifierContext (cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.IdentifierContext)3 VexContext (cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.VexContext)3 VexAnalysisLauncher (cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.VexAnalysisLauncher)3 Argument (cz.startnet.utils.pgdiff.schema.Argument)3 GenericColumn (cz.startnet.utils.pgdiff.schema.GenericColumn)3 PgDatabase (cz.startnet.utils.pgdiff.schema.PgDatabase)3 DbObjType (ru.taximaxim.codekeeper.apgdiff.model.difftree.DbObjType)3 PgDiffUtils (cz.startnet.utils.pgdiff.PgDiffUtils)2 Function_column_name_typeContext (cz.startnet.utils.pgdiff.parsers.antlr.SQLParser.Function_column_name_typeContext)2 FuncProcAnalysisLauncher (cz.startnet.utils.pgdiff.parsers.antlr.expr.launcher.FuncProcAnalysisLauncher)2 AbstractSchema (cz.startnet.utils.pgdiff.schema.AbstractSchema)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 ApgdiffConsts (ru.taximaxim.codekeeper.apgdiff.ApgdiffConsts)2 Pair (ru.taximaxim.codekeeper.apgdiff.utils.Pair)2 JdbcQueries (cz.startnet.utils.pgdiff.loader.JdbcQueries)1