Skip to content

Commit b67fdbf

Browse files
authored
Merge pull request IvorySQL#944 from bigplaice/package_II_master
package phase II
2 parents a32b574 + 83cd309 commit b67fdbf

24 files changed

+2057
-521
lines changed

src/backend/commands/tablecmds.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6957,6 +6957,8 @@ alter_table_type_to_string(AlterTableType cmdtype)
69576957
return "ALTER TABLE ... SET WITH ROWID";
69586958
case AT_DropRowids:
69596959
return "ALTER TABLE ... SET WITHOUT ROWID";
6960+
case AT_ForceViewCompile:
6961+
return NULL;
69606962
}
69616963

69626964
return NULL;

src/backend/executor/execExpr.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5122,26 +5122,39 @@ ExecInitFuncWithOutParams(Expr *node, ExprState *state,
51225122
Oid rettype;
51235123
char *funcname = NULL;
51245124

5125-
func_tuple = SearchSysCache1(PROCOID,
5126-
ObjectIdGetDatum(funcOid));
5125+
if (FUNC_EXPR_FROM_PG_PROC(funcexpr->function_from))
5126+
{
5127+
func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
51275128

5128-
if (!HeapTupleIsValid(func_tuple))
5129-
return;
5129+
if (!HeapTupleIsValid(func_tuple))
5130+
return;
51305131

5131-
if (((Form_pg_proc) GETSTRUCT(func_tuple))->prokind != PROKIND_FUNCTION ||
5132-
LANG_PLISQL_OID != ((Form_pg_proc) GETSTRUCT(func_tuple))->prolang)
5132+
if (((Form_pg_proc) GETSTRUCT(func_tuple))->prokind != PROKIND_FUNCTION ||
5133+
LANG_PLISQL_OID != ((Form_pg_proc) GETSTRUCT(func_tuple))->prolang)
5134+
{
5135+
ReleaseSysCache(func_tuple);
5136+
return;
5137+
}
5138+
5139+
/*
5140+
* Get the argument names and modes
5141+
*/
5142+
num_all_args = get_func_arg_info(func_tuple, &argtypes,
5143+
&argnames, &argmodes);
5144+
rettype = get_func_real_rettype(func_tuple);
5145+
funcname = NameStr(((Form_pg_proc) GETSTRUCT(func_tuple))->proname);
5146+
}
5147+
else
51335148
{
5134-
ReleaseSysCache(func_tuple);
5135-
return;
5149+
/* skip procedure */
5150+
if (get_subproc_kind(funcexpr) != PROKIND_FUNCTION)
5151+
return;
5152+
num_all_args = get_subproc_arg_info(funcexpr, &argtypes,
5153+
&argnames, &argmodes);
5154+
rettype = funcexpr->funcresulttype;
5155+
funcname = get_internal_function_name(funcexpr);
51365156
}
51375157

5138-
/*
5139-
* get the argument names and modes
5140-
*/
5141-
num_all_args = get_func_arg_info(func_tuple, &argtypes, &argnames, &argmodes);
5142-
rettype = ((Form_pg_proc) GETSTRUCT(func_tuple))->prorettype;
5143-
funcname = NameStr(((Form_pg_proc) GETSTRUCT(func_tuple))->proname);
5144-
51455158
num_out_args = 0;
51465159
for (i = 0; i < num_all_args; i++)
51475160
{
@@ -5251,6 +5264,7 @@ ExecInitFuncWithOutParams(Expr *node, ExprState *state,
52515264
}
52525265
}
52535266
}
5267+
52545268
if (FUNC_EXPR_FROM_PG_PROC(funcexpr->function_from))
52555269
ReleaseSysCache(func_tuple);
52565270
}

src/backend/executor/execSRF.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "access/htup_details.h"
2222
#include "catalog/objectaccess.h"
23+
#include "executor/spi.h"
2324
#include "catalog/pg_proc.h"
2425
#include "funcapi.h"
2526
#include "miscadmin.h"
@@ -31,6 +32,8 @@
3132
#include "utils/lsyscache.h"
3233
#include "utils/memutils.h"
3334
#include "utils/typcache.h"
35+
#include "utils/ora_compatible.h"
36+
#include "utils/guc.h"
3437

3538

3639
/* static function decls */
@@ -132,7 +135,39 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
132135
MemoryContextReset(argContext);
133136
callerContext = MemoryContextSwitchTo(argContext);
134137

135-
funcrettype = exprType((Node *) setexpr->expr);
138+
if (nodeTag(setexpr->expr) == T_FuncExpr &&
139+
SPI_get_connected() < 0 &&
140+
DB_ORACLE == compatible_db)
141+
{
142+
FuncExpr *funcexpr = (FuncExpr *) setexpr->expr;
143+
Oid resulttype;
144+
int32 chtypmod;
145+
Oid chcollationoid;
146+
147+
funcrettype = exprType((Node *) setexpr->expr);
148+
149+
if (FUNC_EXPR_FROM_PG_PROC(funcexpr->function_from) &&
150+
func_should_change_return_type(funcexpr->funcid, &resulttype, &chtypmod, &chcollationoid))
151+
{
152+
funcrettype = resulttype;
153+
funcexpr->funcresulttype = resulttype;
154+
funcexpr->funccollid = chcollationoid;
155+
}
156+
else if (!FUNC_EXPR_FROM_PG_PROC(funcexpr->function_from) &&
157+
subproc_should_change_return_type(funcexpr,
158+
&resulttype,
159+
&chtypmod,
160+
&chcollationoid))
161+
{
162+
funcrettype = resulttype;
163+
funcexpr->funcresulttype = resulttype;
164+
funcexpr->funccollid = chcollationoid;
165+
}
166+
}
167+
else
168+
{
169+
funcrettype = exprType((Node *) setexpr->expr);
170+
}
136171

137172
returnsTuple = type_is_rowtype(funcrettype);
138173

src/backend/executor/execTuples.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,6 +2205,15 @@ ExecTypeFromTLInternal(List *targetList, bool hasrowid, bool skipjunk)
22052205
func->funcresulttype = resulttype;
22062206
func->funccollid = chcollationoid;
22072207
}
2208+
else if (!FUNC_EXPR_FROM_PG_PROC(func->function_from) &&
2209+
subproc_should_change_return_type(func, &resulttype, &chtypmod, &chcollationoid))
2210+
{
2211+
typoid = resulttype;
2212+
typmod = chtypmod;
2213+
collationoid = chcollationoid;
2214+
func->funcresulttype = resulttype;
2215+
func->funccollid = chcollationoid;
2216+
}
22082217
}
22092218

22102219
TupleDescInitEntry(typeInfo,

src/backend/parser/parse_clause.c

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3955,71 +3955,78 @@ interpretRowidOption(List *defList, bool allowRowid)
39553955
static void
39563956
check_funcexpr_outparams(List *funcexprs)
39573957
{
3958-
HeapTuple procTup;
3959-
Form_pg_proc procStruct;
3960-
char *proname = NULL;
3961-
FuncExpr *func = (FuncExpr *) linitial(funcexprs);
3958+
ListCell *lc;
39623959

3963-
if (list_length(funcexprs) <= 0)
3960+
if (allow_out_parameter_const)
39643961
return;
39653962

3966-
if (!IsA(func, FuncExpr))
3967-
return;
3968-
3969-
if (!FUNC_EXPR_FROM_PG_PROC(func->function_from))
3970-
return;
3963+
foreach (lc, funcexprs)
3964+
{
3965+
FuncExpr *func = (FuncExpr *) lfirst(lc);
3966+
int i;
3967+
ListCell *lc1;
3968+
Oid *argtypes = NULL;
3969+
char **argnames = NULL;
3970+
char *argmodes= NULL;
3971+
HeapTuple procTup = NULL;
3972+
char *proname = NULL;
39713973

3972-
procTup = SearchSysCache1(PROCOID,
3973-
ObjectIdGetDatum(func->funcid));
3974+
if (!IsA(func, FuncExpr))
3975+
return;
39743976

3975-
if (!HeapTupleIsValid(procTup))
3976-
ereport(ERROR,
3977-
(errcode(ERRCODE_DATA_EXCEPTION),
3978-
errmsg("cache lookup failed for function %u", func->funcid)));
3977+
if (FUNC_EXPR_FROM_PG_PROC(func->function_from))
3978+
{
3979+
Form_pg_proc procStruct;
3980+
3981+
procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(func->funcid));
39793982

3980-
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
3983+
if (!HeapTupleIsValid(procTup))
3984+
ereport(ERROR,
3985+
(errcode(ERRCODE_DATA_EXCEPTION),
3986+
errmsg("cache lookup failed for function %u", func->funcid)));
39813987

3982-
if (LANG_PLISQL_OID != procStruct->prolang)
3983-
{
3984-
ReleaseSysCache(procTup);
3985-
return;
3986-
}
3988+
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
39873989

3988-
if (!heap_attisnull(procTup, Anum_pg_proc_proargmodes, NULL) &&
3989-
!allow_out_parameter_const)
3990-
{
3991-
int i;
3992-
ListCell *lc;
3993-
Oid *argtypes;
3994-
char **argnames;
3995-
char *argmodes;
3990+
if (LANG_PLISQL_OID != procStruct->prolang)
3991+
{
3992+
ReleaseSysCache(procTup);
3993+
continue;
3994+
}
39963995

3997-
proname = pstrdup(NameStr(procStruct->proname));
3998-
get_func_arg_info(procTup, &argtypes, &argnames, &argmodes);
3996+
proname = pstrdup(NameStr(procStruct->proname));
3997+
get_func_arg_info(procTup, &argtypes, &argnames, &argmodes);
3998+
ReleaseSysCache(procTup);
39993999

4000+
if (argmodes == NULL)
4001+
continue;
4002+
}
4003+
else
4004+
{
4005+
get_subproc_arg_info(func, &argtypes,
4006+
&argnames, &argmodes);
4007+
proname = get_internal_function_name(func);
4008+
}
40004009
i = 0;
4001-
foreach(lc, func->args)
4010+
4011+
foreach(lc1, func->args)
40024012
{
4013+
40034014
if (argmodes[i] == PROARGMODE_OUT ||
40044015
argmodes[i] == PROARGMODE_INOUT)
40054016
{
4006-
Node *arg = (Node *) lfirst(lc);
4017+
Node *arg = (Node *) lfirst(lc1);
40074018

40084019
arg = ParseParamVariable(arg);
40094020
if (!IsA(arg, Param))
40104021
{
4011-
ReleaseSysCache(procTup);
40124022
ereport(ERROR,
40134023
(errcode(ERRCODE_DATA_EXCEPTION),
4014-
errmsg("OUT or IN OUT arguments of the function %s must be variables ",
4024+
errmsg("OUT or IN OUT arguments of the function %s must be variables.",
40154025
proname)));
40164026
}
40174027
}
40184028
i++;
40194029
}
40204030
}
4021-
ReleaseSysCache(procTup);
4022-
4023-
return;
40244031
}
40254032

src/backend/utils/fmgr/funcapi.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ typedef struct polymorphic_actuals
5151
Oid anymultirange_type; /* anymultirange mapping, if known */
5252
} polymorphic_actuals;
5353

54-
PLiSQL_funcs_call plisql_internal_funcs = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false};
54+
PLiSQL_funcs_call plisql_internal_funcs = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false};
5555

5656
static void shutdown_MultiFuncCall(Datum arg);
5757
static TypeFuncClass internal_get_result_type(Oid funcid,
@@ -1932,6 +1932,52 @@ get_func_typename_info(HeapTuple procTup,
19321932

19331933
}
19341934

1935+
/*
1936+
* get subproc prokind
1937+
*/
1938+
char
1939+
get_subproc_kind(FuncExpr *fexpr)
1940+
{
1941+
plisql_internel_funcs_init();
1942+
1943+
return plisql_internal_funcs.get_subproc_prokind(fexpr);
1944+
}
1945+
1946+
/*
1947+
* get subproc arginfo
1948+
*/
1949+
int
1950+
get_subproc_arg_info(FuncExpr *fexpr,
1951+
Oid **p_argtypes,
1952+
char ***p_argnames,
1953+
char **p_argmodes)
1954+
{
1955+
plisql_internel_funcs_init();
1956+
1957+
return plisql_internal_funcs.get_subproc_arg_info(fexpr,
1958+
p_argtypes,
1959+
p_argnames,
1960+
p_argmodes);
1961+
}
1962+
1963+
/*
1964+
* check if subproc should chanage its return type
1965+
*/
1966+
bool
1967+
subproc_should_change_return_type(FuncExpr *fexpr,
1968+
Oid *rettype,
1969+
int32 *typmod,
1970+
Oid *collationoid)
1971+
{
1972+
plisql_internel_funcs_init();
1973+
1974+
return plisql_internal_funcs.subproc_should_change_return_type(fexpr,
1975+
rettype,
1976+
typmod,
1977+
collationoid);
1978+
}
1979+
1980+
19351981
/*
19361982
* build_function_result_tupdesc_d
19371983
*

src/bin/psql/help.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ slashUsage(unsigned short int pager)
244244
HELP0(" \\dg[Sx+] [PATTERN] list roles\n");
245245
HELP0(" \\di[Sx+] [PATTERN] list indexes\n");
246246
HELP0(" \\dl[x+] list large objects, same as \\lo_list\n");
247+
HELP0(" \\dk[S+] [PATTERN] list packages\n");
247248
HELP0(" \\dL[Sx+] [PATTERN] list procedural languages\n");
248249
HELP0(" \\dm[Sx+] [PATTERN] list materialized views\n");
249250
HELP0(" \\dn[Sx+] [PATTERN] list schemas\n");

src/bin/psql/po/zh_CN.po

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,6 +3005,11 @@ msgstr " \\dg[S+] [模式] 列出角色\n"
30053005
msgid " \\di[S+] [PATTERN] list indexes\n"
30063006
msgstr " \\di[S+] [模式] 列出索引\n"
30073007

3008+
#: help.c:253
3009+
#, c-format
3010+
msgid " \\dk[S+] [PATTERN] list packages\n"
3011+
msgstr " \\dk[S+] [模式] 列出包\n"
3012+
30083013
#: help.c:251
30093014
#, c-format
30103015
msgid " \\dl list large objects, same as \\lo_list\n"

src/include/funcapi.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,15 @@ typedef struct
202202
Oid (*get_top_function_id) (void *function, bool *is_package);
203203
void (*get_subprocs_from_package) (Oid pkgoid, TupleDesc tupdesc,
204204
Tuplestorestate *tupstore);
205+
int (*get_subproc_arg_info) (FuncExpr *fexpr,
206+
Oid **p_argtypes,
207+
char ***p_argnames,
208+
char **p_argmodes);
209+
char (*get_subproc_prokind) (FuncExpr *fexpr);
210+
bool (*subproc_should_change_return_type) (FuncExpr *fexpr,
211+
Oid *rettype,
212+
int32 *typmod,
213+
Oid *collationoid);
205214
void (*compile_inline_internal) (char *proc_source);
206215
void (*function_free) (Oid funcOid);
207216
bool isload;
@@ -269,6 +278,16 @@ extern bool func_should_change_return_type(Oid functionId, Oid *rettype,
269278
extern void get_func_typename_info(HeapTuple procTup,
270279
char ***p_argtypeNames,
271280
char **rettypeName);
281+
extern char get_subproc_kind(FuncExpr *fexpr);
282+
extern int get_subproc_arg_info(FuncExpr *fexpr,
283+
Oid **p_argtypes,
284+
char ***p_argnames,
285+
char **p_argmodes);
286+
extern bool subproc_should_change_return_type(FuncExpr *fexpr,
287+
Oid *rettype,
288+
int32 *typmod,
289+
Oid *collationoid);
290+
272291

273292
extern char get_func_prostatus(HeapTuple procTup);
274293
extern void change_func_prostatus(Oid funcOid, char prostatus);

0 commit comments

Comments
 (0)