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

pg_query_parse_plpgsql does not support function with sql_body #245

Open
MGorkov opened this issue Apr 23, 2024 · 1 comment
Open

pg_query_parse_plpgsql does not support function with sql_body #245

MGorkov opened this issue Apr 23, 2024 · 1 comment
Labels

Comments

@MGorkov
Copy link

MGorkov commented Apr 23, 2024

When parsing function with sql_body (docs) the pg_query_parse_plpgsql aborts with error:
"src/pg_query_parse_plpgsql.c:143: compile_create_function_stmt: Assertion 'proc_source != NULL' failed."

simple_plpgsql.c :

#include <pg_query.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
  PgQueryPlpgsqlParseResult result;

  result = pg_query_parse_plpgsql(" \
  CREATE OR REPLACE FUNCTION add(a integer, b integer) \
RETURNS integer \
LANGUAGE SQL \
IMMUTABLE \
STRICT \
RETURN a + b;");

  if (result.error) {
    printf("error: %s at %d\n", result.error->message, result.error->cursorpos);
  } else {
    printf("%s\n", result.plpgsql_funcs);
  }

  pg_query_free_plpgsql_parse_result(result);

  // Optional, this ensures all memory is freed upon program exit (useful when running Valgrind)
  pg_query_exit();

  return 0;
}
@lfittl
Copy link
Member

lfittl commented Apr 26, 2024

@MGorkov Thanks for reaching out!

This style of writing a function only works for SQL functions, not PL/pgSQL. The pg_query_parse_plpgsql function is intended to be used for parsing PL/pgSQL, and as such does not support the sql_body syntax.

Instead for SQL functions you should use the regular parse function, as that will be able to read sql_body:

#include <pg_query.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
  PgQueryParseResult result;

  result = pg_query_parse(" \
  CREATE OR REPLACE FUNCTION add(a integer, b integer) \
RETURNS integer \
LANGUAGE SQL \
IMMUTABLE \
STRICT \
RETURN a + b;");

  if (result.error) {
    printf("error: %s at %d\n", result.error->message, result.error->cursorpos);
  } else {
    printf("%s\n", result.parse_tree);
  }

  pg_query_free_parse_result(result);

  // Optional, this ensures all memory is freed upon program exit (useful when running Valgrind)
  pg_query_exit();

  return 0;
}
{
    "version": 160001,
    "stmts": [
        {
            "stmt": {
                "CreateFunctionStmt": {
                    // ...
                    ],
                    "sql_body": {
                        "ReturnStmt": {
                            "returnval": {
                                "A_Expr": {
                                    "kind": "AEXPR_OP",
                                    "name": [
                                        {
                                            "String": {
                                                "sval": "+"
                                            }
                                        }
                                    ],
                                    "lexpr": {
                                        "ColumnRef": {
                                            "fields": [
                                                {
                                                    "String": {
                                                        "sval": "a"
                                                    }
                                                }
                                            ],
                                            "location": 109
                                        }
                                    },
                                    "rexpr": {
                                        "ColumnRef": {
                                            "fields": [
                                                {
                                                    "String": {
                                                        "sval": "b"
                                                    }
                                                }
                                            ],
                                            "location": 113
                                        }
                                    },
                                    "location": 111
                                }
                            }
                        }
                    }
                }
            },
            "stmt_len": 114
        }
    ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants