Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for create procedure #85

Merged
merged 1 commit into from
Dec 18, 2023

Conversation

cvng
Copy link
Contributor

@cvng cvng commented Dec 17, 2023

What kind of change does this PR introduce?

add support for create procedure

What is the current behavior?

panics

What is the new behavior?

parser returns
test_create_procedure passes but parser produces incorrect tree

View log
CreateFunctionStmt {
    is_procedure: true,
    replace: false,
    funcname: [
        Node {
            node: Some(
                String(
                    String {
                        sval: "insert_data",
                    },
                ),
            ),
        },
    ],
    parameters: [
        Node {
            node: Some(
                FunctionParameter(
                    FunctionParameter {
                        name: "a",
                        arg_type: Some(
                            TypeName {
                                names: [
                                    Node {
                                        node: Some(
                                            String(
                                                String {
                                                    sval: "pg_catalog",
                                                },
                                            ),
                                        ),
                                    },
                                    Node {
                                        node: Some(
                                            String(
                                                String {
                                                    sval: "int4",
                                                },
                                            ),
                                        ),
                                    },
                                ],
                                type_oid: 0,
                                setof: false,
                                pct_type: false,
                                typmods: [],
                                typemod: -1,
                                array_bounds: [],
                                location: 31,
                            },
                        ),
                        mode: FuncParamDefault,
                        defexpr: None,
                    },
                ),
            ),
        },
    ],
    return_type: None,
    options: [
        Node {
            node: Some(
                DefElem(
                    DefElem {
                        defnamespace: "",
                        defname: "language",
                        arg: Some(
                            Node {
                                node: Some(
                                    String(
                                        String {
                                            sval: "sql",
                                        },
                                    ),
                                ),
                            },
                        ),
                        defaction: DefelemUnspec,
                        location: 56,
                    },
                ),
            ),
        },
        Node {
            node: Some(
                DefElem(
                    DefElem {
                        defnamespace: "",
                        defname: "as",
                        arg: Some(
                            Node {
                                node: Some(
                                    List(
                                        List {
                                            items: [
                                                Node {
                                                    node: Some(
                                                        String(
                                                            String {
                                                                sval: "insert into tbl values (a);",
                                                            },
                                                        ),
                                                    ),
                                                },
                                            ],
                                        },
                                    ),
                                ),
                            },
                        ),
                        defaction: DefelemUnspec,
                        location: 85,
                    },
                ),
            ),
        },
    ],
    sql_body: None,
}

Additional context

It looks like create procedure is parsed as an insert in valid_statements, when sql_body is not $$ dollar-quoted:

CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL BEGIN ATOMIC INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); END;
View log
[2023-12-17T15:40:44Z DEBUG statement_parser_test] Parsing statement 0052
    CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL BEGIN ATOMIC INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); END;
    
[2023-12-17T15:40:44Z DEBUG parser::parser] start_node: SourceFile
[2023-12-17T15:40:44Z DEBUG parser::parse::libpg_query_node] Parsing node InsertStmt(
        InsertStmt {
            relation: Some(
                RangeVar {
                    catalogname: "",
                    schemaname: "",
                    relname: "tbl",
                    inh: true,
                    relpersistence: "p",
                    alias: None,
                    location: 12,
                },
            ),
            cols: [],
            select_stmt: Some(
                Node {
                    node: Some(
                        SelectStmt(
                            SelectStmt {
                                distinct_clause: [],
                                into_clause: None,
                                target_list: [],
                                from_clause: [],
                                where_clause: None,
                                group_clause: [],
                                group_distinct: false,
                                having_clause: None,
                                window_clause: [],
                                values_lists: [
                                    Node {
                                        node: Some(
                                            List(
                                                List {
                                                    items: [
                                                        Node {
                                                            node: Some(
                                                                ColumnRef(
                                                                    ColumnRef {
                                                                        fields: [
                                                                            Node {
                                                                                node: Some(
                                                                                    String(
                                                                                        String {
                                                                                            sval: "a",
                                                                                        },
                                                                                    ),
                                                                                ),
                                                                            },
                                                                        ],
                                                                        location: 24,
                                                                    },
                                                                ),
                                                            ),
                                                        },
                                                    ],
                                                },
                                            ),
                                        ),
                                    },
                                ],
                                sort_clause: [],
                                limit_offset: None,
                                limit_count: None,
                                limit_option: Default,
                                locking_clause: [],
                                with_clause: None,
                                op: SetopNone,
                                all: false,
                                larg: None,
                                rarg: None,
                            },
                        ),
                    ),
                },
            ),
            on_conflict_clause: None,
            returning_list: [],
            with_clause: None,
            r#override: OverridingNotSet,
        },
    )
Parsing node InsertStmt(
    InsertStmt {
        relation: Some(
            RangeVar {
                catalogname: "",
                schemaname: "",
                relname: "tbl",
                inh: true,
                relpersistence: "p",
                alias: None,
                location: 12,
            },
        ),
        cols: [],
        select_stmt: Some(
            Node {
                node: Some(
                    SelectStmt(
                        SelectStmt {
                            distinct_clause: [],
                            into_clause: None,
                            target_list: [],
                            from_clause: [],
                            where_clause: None,
                            group_clause: [],
                            group_distinct: false,
                            having_clause: None,
                            window_clause: [],
                            values_lists: [
                                Node {
                                    node: Some(
                                        List(
                                            List {
                                                items: [
                                                    Node {
                                                        node: Some(
                                                            ColumnRef(
                                                                ColumnRef {
                                                                    fields: [
                                                                        Node {
                                                                            node: Some(
                                                                                String(
                                                                                    String {
                                                                                        sval: "a",
                                                                                    },
                                                                                ),
                                                                            ),
                                                                        },
                                                                    ],
                                                                    location: 24,
                                                                },
                                                            ),
                                                        ),
                                                    },
                                                ],
                                            },
                                        ),
                                    ),
                                },
                            ],
                            sort_clause: [],
                            limit_offset: None,
                            limit_count: None,
                            limit_option: Default,
                            locking_clause: [],
                            with_clause: None,
                            op: SetopNone,
                            all: false,
                            larg: None,
                            rarg: None,
                        },
                    ),
                ),
            },
        ),
        on_conflict_clause: None,
        returning_list: [],
        with_clause: None,
        r#override: OverridingNotSet,
    },
)
[crates/parser/src/parse/libpg_query_node.rs:67] &self.node_graph = StableGraph {
    Ty: "Directed",
    node_count: 5,
    edge_count: 4,
    edges: (0, 1), (0, 2), (2, 3), (3, 4),
    node weights: {
        0: Node {
            kind: InsertStmt,
            depth: 1,
            properties: [
                TokenProperty {
                    value: None,
                    kind: Some(
                        Insert,
                    ),
                },
                TokenProperty {
                    value: None,
                    kind: Some(
                        Into,
                    ),
                },
            ],
            location: None,
        },
        1: Node {
            kind: RangeVar,
            depth: 2,
            properties: [
                TokenProperty {
                    value: Some(
                        "tbl",
                    ),
                    kind: None,
                },
                TokenProperty {
                    value: Some(
                        "p",
                    ),
                    kind: None,
                },
            ],
            location: Some(
                12,
            ),
        },
        2: Node {
            kind: SelectStmt,
            depth: 2,
            properties: [
                TokenProperty {
                    value: None,
                    kind: Some(
                        Select,
                    ),
                },
                TokenProperty {
                    value: None,
                    kind: Some(
                        Values,
                    ),
                },
            ],
            location: None,
        },
        3: Node {
            kind: List,
            depth: 3,
            properties: [],
            location: None,
        },
        4: Node {
            kind: ColumnRef,
            depth: 4,
            properties: [
                TokenProperty {
                    value: Some(
                        "a",
                    ),
                    kind: None,
                },
            ],
            location: Some(
                24,
            ),
        },
    },
    free_node: NodeIndex(4294967295),
    free_edge: EdgeIndex(4294967295),
}

@psteinroe
Copy link
Collaborator

It looks like create procedure is parsed as an insert in valid_statements, when sql_body is not $$ dollar-quoted:

this must be fixed in the statement parser. will do so this week!

@cvng cvng marked this pull request as draft December 18, 2023 16:28
@psteinroe
Copy link
Collaborator

@cvng this is now ready isn't it?

@cvng
Copy link
Contributor Author

cvng commented Dec 18, 2023

@psteinroe let me rebase and check real quick

@cvng cvng marked this pull request as ready for review December 18, 2023 21:39
@psteinroe psteinroe merged commit eccfe1c into supabase-community:main Dec 18, 2023
1 check passed
@cvng cvng deleted the feat/create-proc branch December 18, 2023 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants