From 0e2ff20478597f430ecf4b68d0f4ddf6c3246c51 Mon Sep 17 00:00:00 2001 From: "me.gorkov" Date: Wed, 8 May 2024 13:21:18 +0300 Subject: [PATCH] add aliasfor --- src/pg_query_json_plpgsql.c | 2 ++ src/postgres/include/plpgsql.h | 3 +++ src/postgres/src_pl_plpgsql_src_pl_comp.c | 2 ++ src/postgres/src_pl_plpgsql_src_pl_gram.c | 15 +++++++++++++++ test/plpgsql_samples.expected.json | 7 ++++--- test/plpgsql_samples.sql | 11 +++++++++++ 6 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/pg_query_json_plpgsql.c b/src/pg_query_json_plpgsql.c index 8a3b370c..dc110dab 100644 --- a/src/pg_query_json_plpgsql.c +++ b/src/pg_query_json_plpgsql.c @@ -679,6 +679,7 @@ dump_var(StringInfo out, PLpgSQL_var *node) WRITE_NODE_TYPE("PLpgSQL_var"); WRITE_STRING_FIELD(refname, refname, refname); + WRITE_STRING_FIELD(aliasfor, aliasfor, aliasfor); WRITE_INT_FIELD(lineno, lineno, lineno); WRITE_OBJ_FIELD(datatype, dump_type); WRITE_BOOL_FIELD(isconst, isconst, isconst); @@ -753,6 +754,7 @@ dump_record(StringInfo out, PLpgSQL_rec *node) { WRITE_NODE_TYPE("PLpgSQL_rec"); WRITE_STRING_FIELD(refname, refname, refname); + WRITE_STRING_FIELD(aliasfor, aliasfor, aliasfor); WRITE_INT_FIELD(dno, dno, dno); WRITE_INT_FIELD(lineno, lineno, lineno); } diff --git a/src/postgres/include/plpgsql.h b/src/postgres/include/plpgsql.h index 457b319f..8d5d0a92 100644 --- a/src/postgres/include/plpgsql.h +++ b/src/postgres/include/plpgsql.h @@ -290,6 +290,7 @@ typedef struct PLpgSQL_variable PLpgSQL_datum_type dtype; int dno; char *refname; + char *aliasfor; int lineno; bool isconst; bool notnull; @@ -312,6 +313,7 @@ typedef struct PLpgSQL_var PLpgSQL_datum_type dtype; int dno; char *refname; + char *aliasfor; int lineno; bool isconst; bool notnull; @@ -392,6 +394,7 @@ typedef struct PLpgSQL_rec PLpgSQL_datum_type dtype; int dno; char *refname; + char *aliasfor; int lineno; bool isconst; bool notnull; diff --git a/src/postgres/src_pl_plpgsql_src_pl_comp.c b/src/postgres/src_pl_plpgsql_src_pl_comp.c index 83e962d2..a1463bf1 100644 --- a/src/postgres/src_pl_plpgsql_src_pl_comp.c +++ b/src/postgres/src_pl_plpgsql_src_pl_comp.c @@ -751,6 +751,7 @@ plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, var = palloc0(sizeof(PLpgSQL_var)); var->dtype = PLPGSQL_DTYPE_VAR; var->refname = pstrdup(refname); + var->aliasfor = NULL; var->lineno = lineno; var->datatype = dtype; /* other fields are left as 0, might be changed by caller */ @@ -808,6 +809,7 @@ plpgsql_build_record(const char *refname, int lineno, rec = palloc0(sizeof(PLpgSQL_rec)); rec->dtype = PLPGSQL_DTYPE_REC; rec->refname = pstrdup(refname); + rec->aliasfor = NULL; rec->lineno = lineno; /* other fields are left as 0, might be changed by caller */ rec->datatype = dtype; diff --git a/src/postgres/src_pl_plpgsql_src_pl_gram.c b/src/postgres/src_pl_plpgsql_src_pl_gram.c index 5529cad4..864294a8 100644 --- a/src/postgres/src_pl_plpgsql_src_pl_gram.c +++ b/src/postgres/src_pl_plpgsql_src_pl_gram.c @@ -2612,6 +2612,21 @@ yyparse () case 25: #line 530 "pl_gram.y" { + // nsitem->itemno is the associated PLpgSQL_datum's dno , so set aliasfor to associated var/rec refname + if (plpgsql_Datums[(yyvsp[(4) - (5)].nsitem)->itemno]->dtype == PLPGSQL_DTYPE_REC) + { + PLpgSQL_rec *rec = plpgsql_Datums[(yyvsp[(4) - (5)].nsitem)->itemno]; + PLpgSQL_rec *alias = plpgsql_build_record((yyvsp[(1) - (5)].varname).name, (yyvsp[(1) - (5)].varname).lineno, NULL, RECORDOID, false); + alias->aliasfor = rec->refname; + } + else if (plpgsql_Datums[(yyvsp[(4) - (5)].nsitem)->itemno]->dtype == PLPGSQL_DTYPE_VAR) + { + PLpgSQL_var *var = plpgsql_Datums[(yyvsp[(4) - (5)].nsitem)->itemno]; + PLpgSQL_variable *alias = plpgsql_build_variable((yyvsp[(1) - (5)].varname).name, (yyvsp[(1) - (5)].varname).lineno, + var->datatype, false); + alias->aliasfor = var->refname; + } + plpgsql_ns_additem((yyvsp[(4) - (5)].nsitem)->itemtype, (yyvsp[(4) - (5)].nsitem)->itemno, (yyvsp[(1) - (5)].varname).name); ;} diff --git a/test/plpgsql_samples.expected.json b/test/plpgsql_samples.expected.json index 4517cb12..005ace88 100644 --- a/test/plpgsql_samples.expected.json +++ b/test/plpgsql_samples.expected.json @@ -16,12 +16,13 @@ {"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}},{"PLpgSQL_recfield":{"fieldname":"key","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_execsql":{"lineno":3,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO list(key,date) VALUES(NEW.key,NEW.end)","parseMode":0}}}},{"PLpgSQL_stmt_return":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"NEW","parseMode":2}}}}]}}}}, {"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"p_time_start","datatype":{"PLpgSQL_type":{"typname":"timestamptz"}}}},{"PLpgSQL_var":{"refname":"p_time_end","datatype":{"PLpgSQL_type":{"typname":"timestamptz"}}}},{"PLpgSQL_var":{"refname":"p_time_interval","datatype":{"PLpgSQL_type":{"typname":"interval"}}}},{"PLpgSQL_var":{"refname":"ts","datatype":{"PLpgSQL_type":{"typname":"timestamptz"}}}},{"PLpgSQL_var":{"refname":"arbitrary_return","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_if":{"lineno":6,"cond":{"PLpgSQL_expr":{"query":"p_time_interval IS NULL","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"p_time_interval := interval_from_start_end(p_time_start, p_time_end)","parseMode":3}}}}]}},{"PLpgSQL_stmt_return_query":{"lineno":9,"query":{"PLpgSQL_expr":{"query":"SELECT\n bucket_function(p_time_interval, timestamp) AS ts,\n arbitrary_return\n FROM test.some_table\n WHERE\n start \u003e= p_time_start\n AND \"end\" \u003c p_time_end\n GROUP BY 1","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}}, {"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"_result","datatype":{"PLpgSQL_type":{"typname":"uuid"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_var":{"refname":"active_on_to_date","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"uuid[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_assign":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"_result := ARRAY( SELECT some_id FROM some_table)","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}}, -{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"v_name","datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"v_version","datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_var":{"refname":"_a","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_if":{"lineno":6,"cond":{"PLpgSQL_expr":{"query":"v_version IS NULL","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"v_name","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"v_name || '/' || v_version","parseMode":2}}}}]}}}}, +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"v_name","datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"v_version","datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_var":{"refname":"_a","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_v_name_alias","aliasfor":"v_name","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"varchar"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_if":{"lineno":6,"cond":{"PLpgSQL_expr":{"query":"v_version IS NULL","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"v_name","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"v_name || '/' || v_version","parseMode":2}}}}]}}}}, {"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"str","datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_rec":{"refname":"v3","dno":2,"lineno":3}},{"PLpgSQL_var":{"refname":"v4","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_recfield":{"fieldname":"c1","recparentno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"select 1 as c1, 2 as c2","parseMode":0}},"into":true,"target":{"PLpgSQL_rec":{"refname":"v3","dno":2,"lineno":3}}}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":4,"expr":{"PLpgSQL_expr":{"query":"v3.c1 := 4","parseMode":4}}}},{"PLpgSQL_stmt_return":{}}]}}}}, {"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assert":{"lineno":3,"cond":{"PLpgSQL_expr":{"query":"true","parseMode":2}}}},{"PLpgSQL_stmt_assert":{"lineno":4,"cond":{"PLpgSQL_expr":{"query":"now() \u003c '2000-01-01'","parseMode":2}}}},{"PLpgSQL_stmt_assert":{"lineno":5,"cond":{"PLpgSQL_expr":{"query":"false","parseMode":2}},"message":{"PLpgSQL_expr":{"query":"'msg'","parseMode":2}}}},{"PLpgSQL_stmt_assert":{"lineno":6,"cond":{"PLpgSQL_expr":{"query":"false","parseMode":2}},"message":{"PLpgSQL_expr":{"query":"version()","parseMode":2}}}},{"PLpgSQL_stmt_return":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"1","parseMode":2}}}}]}}}}, {"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":1}},{"PLpgSQL_recfield":{"fieldname":"table_schema","recparentno":1}},{"PLpgSQL_recfield":{"fieldname":"table_name","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fors":{"lineno":3,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":1}},"body":[{"PLpgSQL_stmt_dynexecute":{"lineno":6,"query":{"PLpgSQL_expr":{"query":"'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser'","parseMode":2}}}}],"query":{"PLpgSQL_expr":{"query":"SELECT table_schema, table_name FROM information_schema.tables\n WHERE table_type = 'VIEW' AND table_schema = 'public'","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}}, -{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"float4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"subtotal * 0.06","parseMode":2}}}}]}}}}, +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"float4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_var":{"refname":"subtotal","aliasfor":"$1","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"float4"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"subtotal * 0.06","parseMode":2}}}}]}}}}, {"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_var":{"refname":"local_a","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"text","collation":"en_US"}},"default_val":{"PLpgSQL_expr":{"query":"a","parseMode":2}}}},{"PLpgSQL_var":{"refname":"local_b","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"text"}},"default_val":{"PLpgSQL_expr":{"query":"b","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"local_a \u003c local_b","parseMode":2}}}}]}}}}, {"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_var":{"refname":"ref","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"refcursor"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_open":{"lineno":5,"curvar":1,"cursor_options":256,"query":{"PLpgSQL_expr":{"query":"SELECT col FROM test","parseMode":0}}}},{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"ref","parseMode":2}}}}]}}}}, -{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"s","datatype":{"PLpgSQL_type":{"typname":"int4"}}}},{"PLpgSQL_var":{"refname":"e","datatype":{"PLpgSQL_type":{"typname":"int4"}}}},{"PLpgSQL_var":{"refname":"id","datatype":{"PLpgSQL_type":{"typname":"int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"varno":2,"expr":{"PLpgSQL_expr":{"query":"id := s","parseMode":3}}}},{"PLpgSQL_stmt_loop":{"lineno":4,"body":[{"PLpgSQL_stmt_exit":{"lineno":5,"is_exit":true,"cond":{"PLpgSQL_expr":{"query":"id\u003ee","parseMode":2}}}},{"PLpgSQL_stmt_return_next":{"lineno":6,"retvarno":2}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"id := id + 1","parseMode":3}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"s","datatype":{"PLpgSQL_type":{"typname":"int4"}}}},{"PLpgSQL_var":{"refname":"e","datatype":{"PLpgSQL_type":{"typname":"int4"}}}},{"PLpgSQL_var":{"refname":"id","datatype":{"PLpgSQL_type":{"typname":"int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"varno":2,"expr":{"PLpgSQL_expr":{"query":"id := s","parseMode":3}}}},{"PLpgSQL_stmt_loop":{"lineno":4,"body":[{"PLpgSQL_stmt_exit":{"lineno":5,"is_exit":true,"cond":{"PLpgSQL_expr":{"query":"id\u003ee","parseMode":2}}}},{"PLpgSQL_stmt_return_next":{"lineno":6,"retvarno":2}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"id := id + 1","parseMode":3}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}}, +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"UNKNOWN"}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}},{"PLpgSQL_rec":{"refname":"prior","aliasfor":"old","dno":3,"lineno":3}},{"PLpgSQL_rec":{"refname":"updated","aliasfor":"new","dno":4,"lineno":4}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_return":{"lineno":6}}]}}}} ] diff --git a/test/plpgsql_samples.sql b/test/plpgsql_samples.sql index 9dc14d8d..6e2058db 100644 --- a/test/plpgsql_samples.sql +++ b/test/plpgsql_samples.sql @@ -573,5 +573,16 @@ LOOP id := id + 1; END LOOP; END +$$ + LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION trgfn() + RETURNS trigger AS $$ +DECLARE + prior ALIAS FOR old; + updated ALIAS FOR new; +BEGIN + RETURN; +END; $$ LANGUAGE plpgsql; \ No newline at end of file