Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
970a2d1c
Commit
970a2d1c
authored
Oct 22, 2001
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rebuild cached function definition after CREATE OR REPLACE FUNCTION.
Fix typlen-vs-typmod errors inherited from pltcl.
parent
b2e859a4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
121 additions
and
113 deletions
+121
-113
src/pl/plpython/plpython.c
src/pl/plpython/plpython.c
+121
-113
No files found.
src/pl/plpython/plpython.c
View file @
970a2d1c
...
...
@@ -29,7 +29,7 @@
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.
8 2001/10/06 23:21:45
tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.
9 2001/10/22 19:32:27
tgl Exp $
*
*********************************************************************
*/
...
...
@@ -73,9 +73,8 @@ typedef PyObject *(*PLyDatumToObFunc) (const char *);
typedef
struct
PLyDatumToOb
{
PLyDatumToObFunc
func
;
FmgrInfo
typfunc
;
Oid
typoutput
;
Oid
typelem
;
int2
typlen
;
bool
typbyval
;
}
PLyDatumToOb
;
typedef
struct
PLyTupleToOb
{
...
...
@@ -94,7 +93,7 @@ typedef union PLyTypeInput {
typedef
struct
PLyObToDatum
{
FmgrInfo
typfunc
;
Oid
typelem
;
int2
typlen
;
bool
typbyval
;
}
PLyObToDatum
;
typedef
struct
PLyObToTuple
{
...
...
@@ -121,6 +120,8 @@ typedef struct PLyTypeInfo {
*/
typedef
struct
PLyProcedure
{
char
*
proname
;
TransactionId
fn_xmin
;
CommandId
fn_cmin
;
PLyTypeInfo
result
;
/* also used to store info for trigger tuple type */
PLyTypeInfo
args
[
FUNC_MAX_ARGS
];
int
nargs
;
...
...
@@ -192,11 +193,11 @@ static void PLy_free(void *);
/* sub handlers for functions and triggers
*/
static
Datum
PLy_function_handler
(
PG_FUNCTION_ARGS
,
PLyProcedure
*
);
static
HeapTuple
PLy_trigger_handler
(
PG_FUNCTION_ARGS
,
PLyProcedure
*
);
static
Datum
PLy_function_handler
(
FunctionCallInfo
fcinfo
,
PLyProcedure
*
);
static
HeapTuple
PLy_trigger_handler
(
FunctionCallInfo
fcinfo
,
PLyProcedure
*
);
static
PyObject
*
PLy_function_build_args
(
PG_FUNCTION_ARGS
,
PLyProcedure
*
);
static
PyObject
*
PLy_trigger_build_args
(
PG_FUNCTION_ARGS
,
PLyProcedure
*
,
static
PyObject
*
PLy_function_build_args
(
FunctionCallInfo
fcinfo
,
PLyProcedure
*
);
static
PyObject
*
PLy_trigger_build_args
(
FunctionCallInfo
fcinfo
,
PLyProcedure
*
,
HeapTuple
*
);
static
HeapTuple
PLy_modify_tuple
(
PLyProcedure
*
,
PyObject
*
,
TriggerData
*
,
HeapTuple
);
...
...
@@ -206,12 +207,14 @@ static PyObject *PLy_procedure_call(PLyProcedure *, char *, PyObject *);
/* returns a cached PLyProcedure, or creates, stores and returns
* a new PLyProcedure.
*/
static
PLyProcedure
*
PLy_procedure_get
(
PG_FUNCTION_ARGS
,
bool
);
static
PLyProcedure
*
PLy_procedure_get
(
FunctionCallInfo
fcinfo
,
bool
);
static
PLyProcedure
*
PLy_procedure_create
(
FunctionCallInfo
fcinfo
,
bool
is_trigger
,
HeapTuple
procTup
,
char
*
key
);
static
PLyProcedure
*
PLy_procedure_create
(
PG_FUNCTION_ARGS
,
bool
,
char
*
);
static
void
PLy_procedure_compile
(
PLyProcedure
*
,
const
char
*
);
static
char
*
PLy_procedure_munge_source
(
const
char
*
,
const
char
*
);
static
PLyProcedure
*
PLy_procedure_new
(
const
char
*
name
);
static
void
PLy_procedure_delete
(
PLyProcedure
*
);
static
void
PLy_typeinfo_init
(
PLyTypeInfo
*
);
...
...
@@ -249,7 +252,6 @@ static PyObject *PLy_interp_safe = NULL;
static
PyObject
*
PLy_interp_safe_globals
=
NULL
;
static
PyObject
*
PLy_importable_modules
=
NULL
;
static
PyObject
*
PLy_procedure_cache
=
NULL
;
static
char
*
PLy_procedure_fmt
=
"__plpython_procedure_%s_%u"
;
char
*
PLy_importable_modules_list
[]
=
{
"array"
,
...
...
@@ -387,12 +389,12 @@ plpython_call_handler(PG_FUNCTION_ARGS)
* to take no arguments and return an argument of type opaque.
*/
HeapTuple
PLy_trigger_handler
(
PG_FUNCTION_ARGS
,
PLyProcedure
*
proc
)
PLy_trigger_handler
(
FunctionCallInfo
fcinfo
,
PLyProcedure
*
proc
)
{
DECLARE_EXC
();
HeapTuple
rv
=
NULL
;
PyObject
*
plargs
=
NULL
;
PyObject
*
plrv
=
NULL
;
PyObject
*
volatile
plargs
=
NULL
;
PyObject
*
volatile
plrv
=
NULL
;
enter
();
...
...
@@ -468,12 +470,16 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
HeapTuple
otup
)
{
DECLARE_EXC
();
PyObject
*
plntup
,
*
plkeys
,
*
platt
,
*
plval
,
*
plstr
;
PyObject
*
volatile
plntup
;
PyObject
*
volatile
plkeys
;
PyObject
*
volatile
platt
;
PyObject
*
volatile
plval
;
PyObject
*
volatile
plstr
;
HeapTuple
rtup
;
int
natts
,
i
,
j
,
attn
,
atti
;
int
*
modattrs
;
Datum
*
modvalues
;
char
*
modnulls
;
int
*
volatile
modattrs
;
Datum
*
volatile
modvalues
;
char
*
volatile
modnulls
;
TupleDesc
tupdesc
;
plntup
=
plkeys
=
platt
=
plval
=
plstr
=
NULL
;
...
...
@@ -556,8 +562,8 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
modvalues
[
j
]
=
FunctionCall3
(
&
proc
->
result
.
out
.
r
.
atts
[
atti
].
typfunc
,
CStringGetDatum
(
src
),
proc
->
result
.
out
.
r
.
atts
[
atti
].
typelem
,
proc
->
result
.
out
.
r
.
atts
[
atti
].
typlen
);
ObjectIdGetDatum
(
proc
->
result
.
out
.
r
.
atts
[
atti
].
typelem
)
,
Int32GetDatum
(
tupdesc
->
attrs
[
j
]
->
atttypmod
)
);
modnulls
[
j
]
=
' '
;
Py_DECREF
(
plstr
);
...
...
@@ -588,13 +594,13 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
}
PyObject
*
PLy_trigger_build_args
(
PG_FUNCTION_ARGS
,
PLyProcedure
*
proc
,
HeapTuple
*
rv
)
PLy_trigger_build_args
(
FunctionCallInfo
fcinfo
,
PLyProcedure
*
proc
,
HeapTuple
*
rv
)
{
DECLARE_EXC
();
TriggerData
*
tdata
;
PyObject
*
pltname
,
*
pltevent
,
*
pltwhen
,
*
pltlevel
,
*
pltrelid
;
PyObject
*
pltargs
,
*
pytnew
,
*
pytold
;
PyObject
*
pltdata
=
NULL
;
PyObject
*
volatile
pltdata
=
NULL
;
char
*
stroid
;
enter
();
...
...
@@ -723,13 +729,13 @@ PLy_trigger_build_args(PG_FUNCTION_ARGS, PLyProcedure *proc, HeapTuple *rv)
/* function handler and friends
*/
Datum
PLy_function_handler
(
PG_FUNCTION_ARGS
,
PLyProcedure
*
proc
)
PLy_function_handler
(
FunctionCallInfo
fcinfo
,
PLyProcedure
*
proc
)
{
DECLARE_EXC
();
Datum
rv
;
PyObject
*
plargs
=
NULL
;
PyObject
*
plrv
=
NULL
;
PyObject
*
plrv_so
=
NULL
;
PyObject
*
volatile
plargs
=
NULL
;
PyObject
*
volatile
plrv
=
NULL
;
PyObject
*
volatile
plrv_so
=
NULL
;
char
*
plrv_sc
;
enter
();
...
...
@@ -792,9 +798,9 @@ PLy_function_handler(PG_FUNCTION_ARGS, PLyProcedure *proc)
plrv_so
=
PyObject_Str
(
plrv
);
plrv_sc
=
PyString_AsString
(
plrv_so
);
rv
=
FunctionCall3
(
&
proc
->
result
.
out
.
d
.
typfunc
,
PointerGetDatum
(
plrv_sc
),
proc
->
result
.
out
.
d
.
typelem
,
proc
->
result
.
out
.
d
.
typlen
);
PointerGetDatum
(
plrv_sc
),
ObjectIdGetDatum
(
proc
->
result
.
out
.
d
.
typelem
)
,
Int32GetDatum
(
-
1
)
);
}
RESTORE_EXC
();
...
...
@@ -828,11 +834,11 @@ PLy_procedure_call(PLyProcedure *proc, char *kargs, PyObject *vargs)
}
PyObject
*
PLy_function_build_args
(
PG_FUNCTION_ARGS
,
PLyProcedure
*
proc
)
PLy_function_build_args
(
FunctionCallInfo
fcinfo
,
PLyProcedure
*
proc
)
{
DECLARE_EXC
();
PyObject
*
arg
=
NULL
;
PyObject
*
args
=
NULL
;
PyObject
*
volatile
arg
=
NULL
;
PyObject
*
volatile
args
=
NULL
;
int
i
;
enter
();
...
...
@@ -868,9 +874,9 @@ PLy_function_build_args(PG_FUNCTION_ARGS, PLyProcedure *proc)
Datum
dt
;
dt
=
FunctionCall3
(
&
(
proc
->
args
[
i
].
in
.
d
.
typfunc
),
fcinfo
->
arg
[
i
],
proc
->
args
[
i
].
in
.
d
.
typelem
,
proc
->
args
[
i
].
in
.
d
.
typlen
);
fcinfo
->
arg
[
i
],
ObjectIdGetDatum
(
proc
->
args
[
i
].
in
.
d
.
typelem
)
,
Int32GetDatum
(
-
1
)
);
ct
=
DatumGetCString
(
dt
);
arg
=
(
proc
->
args
[
i
].
in
.
d
.
func
)(
ct
);
pfree
(
ct
);
...
...
@@ -898,45 +904,68 @@ PLy_function_build_args(PG_FUNCTION_ARGS, PLyProcedure *proc)
/* PLyProcedure functions
*/
PLyProcedure
*
PLy_procedure_get
(
PG_FUNCTION_ARGS
,
bool
is_trigger
)
static
PLyProcedure
*
PLy_procedure_get
(
FunctionCallInfo
fcinfo
,
bool
is_trigger
)
{
Oid
fn_oid
;
HeapTuple
procTup
;
char
key
[
128
];
PyObject
*
plproc
;
PLyProcedure
*
proc
;
PLyProcedure
*
proc
=
NULL
;
int
rv
;
enter
();
rv
=
snprintf
(
key
,
sizeof
(
key
),
"%u"
,
fcinfo
->
flinfo
->
fn_oid
);
fn_oid
=
fcinfo
->
flinfo
->
fn_oid
;
procTup
=
SearchSysCache
(
PROCOID
,
ObjectIdGetDatum
(
fn_oid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
procTup
))
elog
(
ERROR
,
"plpython: cache lookup for procedure %u failed"
,
fn_oid
);
rv
=
snprintf
(
key
,
sizeof
(
key
),
"%u%s"
,
fn_oid
,
is_trigger
?
"_trigger"
:
""
);
if
((
rv
>=
sizeof
(
key
))
||
(
rv
<
0
))
elog
(
FATAL
,
"plpython: Buffer overrun in %s:%d"
,
__FILE__
,
__LINE__
);
plproc
=
PyDict_GetItemString
(
PLy_procedure_cache
,
key
);
if
(
plproc
==
NULL
)
return
PLy_procedure_create
(
fcinfo
,
is_trigger
,
key
);
Py_INCREF
(
plproc
);
if
(
!
PyCObject_Check
(
plproc
))
elog
(
FATAL
,
"plpython: Expected a PyCObject, didn't get one"
);
if
(
plproc
!=
NULL
)
{
Py_INCREF
(
plproc
);
if
(
!
PyCObject_Check
(
plproc
))
elog
(
FATAL
,
"plpython: Expected a PyCObject, didn't get one"
);
mark
();
mark
();
proc
=
PyCObject_AsVoidPtr
(
plproc
);
if
(
proc
->
me
!=
plproc
)
elog
(
FATAL
,
"plpython: Aiieee, proc->me != plproc"
);
proc
=
PyCObject_AsVoidPtr
(
plproc
);
if
(
proc
->
me
!=
plproc
)
elog
(
FATAL
,
"plpython: Aiieee, proc->me != plproc"
);
/* did we find an up-to-date cache entry? */
if
(
proc
->
fn_xmin
!=
procTup
->
t_data
->
t_xmin
||
proc
->
fn_cmin
!=
procTup
->
t_data
->
t_cmin
)
{
Py_DECREF
(
plproc
);
proc
=
NULL
;
}
}
if
(
proc
==
NULL
)
proc
=
PLy_procedure_create
(
fcinfo
,
is_trigger
,
procTup
,
key
);
ReleaseSysCache
(
procTup
);
return
proc
;
}
PLyProcedure
*
PLy_procedure_create
(
PG_FUNCTION_ARGS
,
bool
is_trigger
,
char
*
key
)
static
PLyProcedure
*
PLy_procedure_create
(
FunctionCallInfo
fcinfo
,
bool
is_trigger
,
HeapTuple
procTup
,
char
*
key
)
{
char
procName
[
256
];
DECLARE_EXC
();
HeapTuple
procTup
;
Form_pg_proc
procStruct
;
Oid
fn_oid
;
PLyProcedure
*
volatile
proc
;
char
*
volatile
procSource
=
NULL
;
Datum
procDatum
;
...
...
@@ -944,19 +973,28 @@ PLy_procedure_create(PG_FUNCTION_ARGS, bool is_trigger, char *key)
enter
();
fn_oid
=
fcinfo
->
flinfo
->
fn_oid
;
procTup
=
SearchSysCache
(
PROCOID
,
ObjectIdGetDatum
(
fn_oid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
procTup
))
elog
(
ERROR
,
"plpython: cache lookup for procedure
\"
%u
\"
failed"
,
fn_oid
);
procStruct
=
(
Form_pg_proc
)
GETSTRUCT
(
procTup
);
rv
=
snprintf
(
procName
,
sizeof
(
procName
),
PLy_procedure_fmt
,
NameStr
(
procStruct
->
proname
),
fn_oid
);
rv
=
snprintf
(
procName
,
sizeof
(
procName
),
"__plpython_procedure_%s_%u%s"
,
NameStr
(
procStruct
->
proname
),
fcinfo
->
flinfo
->
fn_oid
,
is_trigger
?
"_trigger"
:
""
);
if
((
rv
>=
sizeof
(
procName
))
||
(
rv
<
0
))
elog
(
FATAL
,
"plpython: Procedure name would overrun buffer"
);
proc
=
PLy_procedure_new
(
procName
);
proc
=
PLy_malloc
(
sizeof
(
PLyProcedure
));
proc
->
proname
=
PLy_malloc
(
strlen
(
procName
)
+
1
);
strcpy
(
proc
->
proname
,
procName
);
proc
->
fn_xmin
=
procTup
->
t_data
->
t_xmin
;
proc
->
fn_cmin
=
procTup
->
t_data
->
t_cmin
;
PLy_typeinfo_init
(
&
proc
->
result
);
for
(
i
=
0
;
i
<
FUNC_MAX_ARGS
;
i
++
)
PLy_typeinfo_init
(
&
proc
->
args
[
i
]);
proc
->
nargs
=
0
;
proc
->
code
=
proc
->
interp
=
proc
->
reval
=
proc
->
statics
=
NULL
;
proc
->
globals
=
proc
->
me
=
NULL
;
SAVE_EXC
();
if
(
TRAP_EXC
())
{
...
...
@@ -1037,8 +1075,6 @@ PLy_procedure_create(PG_FUNCTION_ARGS, bool is_trigger, char *key)
PointerGetDatum
(
&
procStruct
->
prosrc
));
procSource
=
DatumGetCString
(
procDatum
);
ReleaseSysCache
(
procTup
);
PLy_procedure_compile
(
proc
,
procSource
);
pfree
(
procSource
);
...
...
@@ -1170,29 +1206,6 @@ PLy_procedure_munge_source(const char *name, const char *src)
return
mrc
;
}
PLyProcedure
*
PLy_procedure_new
(
const
char
*
name
)
{
int
i
;
PLyProcedure
*
proc
;
enter
();
proc
=
PLy_malloc
(
sizeof
(
PLyProcedure
));
proc
->
proname
=
PLy_malloc
(
strlen
(
name
)
+
1
);
strcpy
(
proc
->
proname
,
name
);
PLy_typeinfo_init
(
&
proc
->
result
);
for
(
i
=
0
;
i
<
FUNC_MAX_ARGS
;
i
++
)
PLy_typeinfo_init
(
&
proc
->
args
[
i
]);
proc
->
nargs
=
0
;
proc
->
code
=
proc
->
interp
=
proc
->
reval
=
proc
->
statics
=
NULL
;
proc
->
globals
=
proc
->
me
=
NULL
;
leave
();
return
proc
;
}
void
PLy_procedure_delete
(
PLyProcedure
*
proc
)
{
...
...
@@ -1314,8 +1327,8 @@ PLy_output_datum_func2(PLyObToDatum *arg, Form_pg_type typeStruct)
enter
();
perm_fmgr_info
(
typeStruct
->
typinput
,
&
arg
->
typfunc
);
arg
->
typelem
=
(
Oid
)
typeStruct
->
typelem
;
arg
->
typ
len
=
typeStruct
->
typlen
;
arg
->
typelem
=
typeStruct
->
typelem
;
arg
->
typ
byval
=
typeStruct
->
typbyval
;
}
void
...
...
@@ -1334,10 +1347,9 @@ PLy_input_datum_func2(PLyDatumToOb *arg, Form_pg_type typeStruct)
{
char
*
type
;
arg
->
typoutput
=
typeStruct
->
typoutput
;
perm_fmgr_info
(
typeStruct
->
typoutput
,
&
arg
->
typfunc
);
arg
->
typlen
=
typeStruct
->
typlen
;
arg
->
typelem
=
typeStruct
->
typelem
;
arg
->
typbyval
=
typeStruct
->
typbyval
;
/* hmmm, wierd. means this arg will always be converted
* to a python None
...
...
@@ -1516,9 +1528,10 @@ PLyDict_FromTuple(PLyTypeInfo *info, HeapTuple tuple, TupleDesc desc)
PyDict_SetItemString
(
dict
,
key
,
Py_None
);
else
{
vdat
=
OidFunctionCall3
(
info
->
in
.
r
.
atts
[
i
].
typoutput
,
vattr
,
ObjectIdGetDatum
(
info
->
in
.
r
.
atts
[
i
].
typelem
),
Int32GetDatum
(
info
->
in
.
r
.
atts
[
i
].
typlen
));
vdat
=
FunctionCall3
(
&
info
->
in
.
r
.
atts
[
i
].
typfunc
,
vattr
,
ObjectIdGetDatum
(
info
->
in
.
r
.
atts
[
i
].
typelem
),
Int32GetDatum
(
desc
->
attrs
[
i
]
->
atttypmod
));
vsrc
=
DatumGetCString
(
vdat
);
/* no exceptions allowed
...
...
@@ -1873,7 +1886,7 @@ PLy_spi_prepare(PyObject *self, PyObject *args)
DECLARE_EXC
();
PLyPlanObject
*
plan
;
PyObject
*
list
=
NULL
;
PyObject
*
optr
=
NULL
;
PyObject
*
volatile
optr
=
NULL
;
char
*
query
;
enter
();
...
...
@@ -2037,7 +2050,8 @@ PyObject *
PLy_spi_execute_plan
(
PyObject
*
ob
,
PyObject
*
list
,
int
limit
)
{
DECLARE_EXC
();
int
nargs
,
i
,
rv
;
volatile
int
nargs
;
int
i
,
rv
;
PLyPlanObject
*
plan
;
enter
();
...
...
@@ -2080,12 +2094,10 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, int limit)
*/
for
(
i
=
0
;
i
<
nargs
;
i
++
)
{
/* FIXME -- typbyval the proper check?
*/
if
((
plan
->
values
[
i
]
!=
(
Datum
)
NULL
)
&&
(
plan
->
args
[
i
].
out
.
d
.
typlen
<
0
))
{
pfree
((
void
*
)
plan
->
values
[
i
]);
if
(
!
plan
->
args
[
i
].
out
.
d
.
typbyval
&&
(
plan
->
values
[
i
]
!=
(
Datum
)
NULL
))
{
pfree
(
DatumGetPointer
(
plan
->
values
[
i
]));
plan
->
values
[
i
]
=
(
Datum
)
NULL
;
}
}
...
...
@@ -2100,21 +2112,19 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, int limit)
{
for
(
i
=
0
;
i
<
nargs
;
i
++
)
{
Datum
typelem
,
typlen
,
dv
;
PyObject
*
elem
,
*
so
;
char
*
sv
;
typelem
=
ObjectIdGetDatum
(
plan
->
args
[
i
].
out
.
d
.
typelem
);
typlen
=
Int32GetDatum
(
plan
->
args
[
i
].
out
.
d
.
typlen
);
elem
=
PySequence_GetItem
(
list
,
i
);
so
=
PyObject_Str
(
elem
);
sv
=
PyString_AsString
(
so
);
dv
=
CStringGetDatum
(
sv
);
/* FIXME -- if this can elog, we have leak
*/
plan
->
values
[
i
]
=
FunctionCall3
(
&
(
plan
->
args
[
i
].
out
.
d
.
typfunc
),
dv
,
typelem
,
typlen
);
CStringGetDatum
(
sv
),
ObjectIdGetDatum
(
plan
->
args
[
i
].
out
.
d
.
typelem
),
Int32GetDatum
(
-
1
));
Py_DECREF
(
so
);
Py_DECREF
(
elem
);
...
...
@@ -2126,12 +2136,10 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, int limit)
for
(
i
=
0
;
i
<
nargs
;
i
++
)
{
/* FIXME -- typbyval the proper check?
*/
if
((
plan
->
values
[
i
]
!=
(
Datum
)
NULL
)
&&
(
plan
->
args
[
i
].
out
.
d
.
typlen
<
0
))
if
(
!
plan
->
args
[
i
].
out
.
d
.
typbyval
&&
(
plan
->
values
[
i
]
!=
(
Datum
)
NULL
))
{
pfree
(
(
void
*
)
plan
->
values
[
i
]
);
pfree
(
DatumGetPointer
(
plan
->
values
[
i
])
);
plan
->
values
[
i
]
=
(
Datum
)
NULL
;
}
}
...
...
@@ -2413,11 +2421,11 @@ PLy_notice(PyObject *self, PyObject *args)
PyObject
*
PLy_log
(
int
level
,
PyObject
*
self
,
PyObject
*
args
)
PLy_log
(
volatile
int
level
,
PyObject
*
self
,
PyObject
*
args
)
{
DECLARE_EXC
();
PyObject
*
so
;
char
*
sv
;
char
*
volatile
sv
;
enter
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment