Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions parser/include/pg_query.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ PgQueryDeparseResult pg_query_deparse_protobuf(PgQueryProtobuf parse_tree);
PgQueryDeparseResult pg_query_deparse_expr_protobuf(PgQueryProtobuf parse_tree);
PgQueryDeparseResult pg_query_deparse_typename_protobuf(PgQueryProtobuf parse_tree);
PgQueryDeparseResult pg_query_deparse_reloptions_protobuf(PgQueryProtobuf buf);
PgQueryDeparseResult pg_query_deparse_parenthesized_seq_opt_list_protobuf(PgQueryProtobuf buf);

void pg_query_free_normalize_result(PgQueryNormalizeResult result);
void pg_query_free_scan_result(PgQueryScanResult result);
Expand Down
26 changes: 26 additions & 0 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ PgQueryDeparseResult pg_query_deparse_reloptions_protobuf_direct_args(void* data
return pg_query_deparse_reloptions_protobuf(p);
}

// Avoid complexities dealing with C structs in Go
PgQueryDeparseResult pg_query_deparse_parenthesized_seq_opt_list(void* data, unsigned int len) {
PgQueryProtobuf p;
p.data = (char *) data;
p.len = len;
return pg_query_deparse_parenthesized_seq_opt_list_protobuf(p);
}

// Avoid inconsistent type behaviour in xxhash library
uint64_t pg_query_hash_xxh3_64(void *data, size_t len, size_t seed) {
return XXH3_64bits_withSeed(data, len, seed);
Expand Down Expand Up @@ -216,6 +224,24 @@ func DeparseRelOptionsFromProtobuf(input []byte) (result string, err error) {
return
}

func DeparseParenthesizedSeqOptList(input []byte) (result string, err error) {
inputC := C.CBytes(input)
defer C.free(inputC)

resultC := C.pg_query_deparse_parenthesized_seq_opt_list(inputC, C.uint(len(input)))

defer C.pg_query_free_deparse_result(resultC)

if resultC.error != nil {
err = newPgQueryError(resultC.error)
return
}

result = C.GoString(resultC.query)

return
}

// ParsePlPgSqlToJSON - Parses the given PL/pgSQL function statement into a parse tree (JSON format)
func ParsePlPgSqlToJSON(input string) (result string, err error) {
inputC := C.CString(input)
Expand Down
46 changes: 46 additions & 0 deletions parser/pg_query_deparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,52 @@ PgQueryDeparseResult pg_query_deparse_reloptions_protobuf(PgQueryProtobuf buf)
return result;
}

PgQueryDeparseResult pg_query_deparse_parenthesized_seq_opt_list_protobuf(PgQueryProtobuf buf)
{
PgQueryDeparseResult result = {0};
StringInfoData str;
MemoryContext ctx;
List *list;

ctx = pg_query_enter_memory_context();

PG_TRY();
{
list = pg_query_protobuf_to_list(buf);

initStringInfo(&str);

deparseOptParenthesizedSeqOptList(&str, list);

result.query = strdup(str.data);
}
PG_CATCH();
{
ErrorData* error_data;
PgQueryError* error;

MemoryContextSwitchTo(ctx);
error_data = CopyErrorData();

// Note: This is intentionally malloc so exiting the memory context doesn't free this
error = malloc(sizeof(PgQueryError));
error->message = strdup(error_data->message);
error->filename = strdup(error_data->filename);
error->funcname = strdup(error_data->funcname);
error->context = NULL;
error->lineno = error_data->lineno;
error->cursorpos = error_data->cursorpos;

result.error = error;
FlushErrorState();
}
PG_END_TRY();

pg_query_exit_memory_context(ctx);

return result;
}

void pg_query_free_deparse_result(PgQueryDeparseResult result)
{
if (result.error) {
Expand Down
2 changes: 1 addition & 1 deletion parser/postgres_deparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ static void deparseOptSeqOptList(StringInfo str, List *options)
}

// "OptParenthesizedSeqOptList" in gram.y
static void deparseOptParenthesizedSeqOptList(StringInfo str, List *options)
void deparseOptParenthesizedSeqOptList(StringInfo str, List *options)
{
if (list_length(options) > 0)
{
Expand Down
1 change: 1 addition & 0 deletions parser/postgres_deparse.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ extern void deparseRawStmt(StringInfo str, RawStmt *raw_stmt);
extern void deparseExpr(StringInfo str, Node *node);
extern void deparseTypeName(StringInfo str, TypeName *type_name);
extern void deparseRelOptions(StringInfo str, List *l);
extern void deparseOptParenthesizedSeqOptList(StringInfo str, List *l);

#endif
12 changes: 12 additions & 0 deletions pg_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ func DeparseRelOptions(relOptions []*Node) (output string, err error) {
return
}

func DeparseParenthesizedSeqOptList(seqOptions []*Node) (output string, err error) {
list := MakeListNode(seqOptions)

protobufNode, err := proto.Marshal(list.GetList())
if err != nil {
return
}

output, err = parser.DeparseParenthesizedSeqOptList(protobufNode)
return
}

// ParsePlPgSqlToJSON - Parses the given PL/pgSQL function statement into a parse tree (JSON format)
func ParsePlPgSqlToJSON(input string) (result string, err error) {
return parser.ParsePlPgSqlToJSON(input)
Expand Down