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
1d0d8d3c
Commit
1d0d8d3c
authored
Nov 18, 2005
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Mop-up for nulls-in-arrays patch: fix some places that access array
contents directly.
parent
3201b7f3
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
233 additions
and
278 deletions
+233
-278
contrib/dblink/dblink.c
contrib/dblink/dblink.c
+115
-197
contrib/tsearch2/rank.c
contrib/tsearch2/rank.c
+14
-7
contrib/tsearch2/snowball/header.h
contrib/tsearch2/snowball/header.h
+0
-3
contrib/tsearch2/ts_cfg.c
contrib/tsearch2/ts_cfg.c
+2
-0
src/backend/utils/adt/acl.c
src/backend/utils/adt/acl.c
+37
-10
src/backend/utils/adt/varlena.c
src/backend/utils/adt/varlena.c
+39
-13
src/include/utils/acl.h
src/include/utils/acl.h
+4
-21
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/pl_exec.c
+22
-27
No files found.
contrib/dblink/dblink.c
View file @
1d0d8d3c
...
...
@@ -73,6 +73,7 @@ static HTAB *createConnHash(void);
static
void
createNewConnection
(
const
char
*
name
,
remoteConn
*
rconn
);
static
void
deleteConnection
(
const
char
*
name
);
static
char
**
get_pkey_attnames
(
Oid
relid
,
int16
*
numatts
);
static
char
**
get_text_array_contents
(
ArrayType
*
array
,
int
*
numitems
);
static
char
*
get_sql_insert
(
Oid
relid
,
int2vector
*
pkattnums
,
int16
pknumatts
,
char
**
src_pkattvals
,
char
**
tgt_pkattvals
);
static
char
*
get_sql_delete
(
Oid
relid
,
int2vector
*
pkattnums
,
int16
pknumatts
,
char
**
tgt_pkattvals
);
static
char
*
get_sql_update
(
Oid
relid
,
int2vector
*
pkattnums
,
int16
pknumatts
,
char
**
src_pkattvals
,
char
**
tgt_pkattvals
);
...
...
@@ -1120,29 +1121,18 @@ PG_FUNCTION_INFO_V1(dblink_build_sql_insert);
Datum
dblink_build_sql_insert
(
PG_FUNCTION_ARGS
)
{
text
*
relname_text
=
PG_GETARG_TEXT_P
(
0
);
int2vector
*
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
int32
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
ArrayType
*
src_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
ArrayType
*
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
4
);
Oid
relid
;
text
*
relname_text
;
int2vector
*
pkattnums
;
int
pknumatts_tmp
;
int16
pknumatts
=
0
;
char
**
src_pkattvals
;
char
**
tgt_pkattvals
;
ArrayType
*
src_pkattvals_arry
;
ArrayType
*
tgt_pkattvals_arry
;
int
src_ndim
;
int
*
src_dim
;
int
src_nitems
;
int
tgt_ndim
;
int
*
tgt_dim
;
int
tgt_nitems
;
int
i
;
char
*
ptr
;
char
*
sql
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
relname_text
=
PG_GETARG_TEXT_P
(
0
);
/*
* Convert relname to rel OID.
...
...
@@ -1154,34 +1144,27 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
errmsg
(
"relation
\"
%s
\"
does not exist"
,
GET_STR
(
relname_text
))));
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* There should be at least one key attribute
*/
if
(
pknumatts
=
=
0
)
if
(
pknumatts
_tmp
<
=
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"number of key attributes must be > 0"
)));
src_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
4
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* Source array is made up of key values that will be used to locate the
* tuple of interest from the local system.
*/
src_ndim
=
ARR_NDIM
(
src_pkattvals_arry
);
src_dim
=
ARR_DIMS
(
src_pkattvals_arry
);
src_nitems
=
ArrayGetNItems
(
src_ndim
,
src_dim
);
src_pkattvals
=
get_text_array_contents
(
src_pkattvals_arry
,
&
src_nitems
);
/*
* There should be one source array key value for each key attnum
...
...
@@ -1192,29 +1175,11 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
errmsg
(
"source key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input source array
*/
Assert
(
ARR_ELEMTYPE
(
src_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
src_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
src_pkattvals
=
(
char
**
)
palloc
(
src_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
src_pkattvals_arry
);
for
(
i
=
0
;
i
<
src_nitems
;
i
++
)
{
src_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Target array is made up of key values that will be used to build the
* SQL string for use on the remote system.
*/
tgt_ndim
=
ARR_NDIM
(
tgt_pkattvals_arry
);
tgt_dim
=
ARR_DIMS
(
tgt_pkattvals_arry
);
tgt_nitems
=
ArrayGetNItems
(
tgt_ndim
,
tgt_dim
);
tgt_pkattvals
=
get_text_array_contents
(
tgt_pkattvals_arry
,
&
tgt_nitems
);
/*
* There should be one target array key value for each key attnum
...
...
@@ -1225,22 +1190,6 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
errmsg
(
"target key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input target array
*/
Assert
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
tgt_pkattvals
=
(
char
**
)
palloc
(
tgt_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
tgt_pkattvals_arry
);
for
(
i
=
0
;
i
<
tgt_nitems
;
i
++
)
{
tgt_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Prep work is finally done. Go get the SQL string.
*/
...
...
@@ -1272,24 +1221,15 @@ PG_FUNCTION_INFO_V1(dblink_build_sql_delete);
Datum
dblink_build_sql_delete
(
PG_FUNCTION_ARGS
)
{
text
*
relname_text
=
PG_GETARG_TEXT_P
(
0
);
int2vector
*
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
int32
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
ArrayType
*
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
Oid
relid
;
text
*
relname_text
;
int2vector
*
pkattnums
;
int
pknumatts_tmp
;
int16
pknumatts
=
0
;
char
**
tgt_pkattvals
;
ArrayType
*
tgt_pkattvals_arry
;
int
tgt_ndim
;
int
*
tgt_dim
;
int
tgt_nitems
;
int
i
;
char
*
ptr
;
char
*
sql
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
relname_text
=
PG_GETARG_TEXT_P
(
0
);
/*
* Convert relname to rel OID.
...
...
@@ -1301,33 +1241,27 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
errmsg
(
"relation
\"
%s
\"
does not exist"
,
GET_STR
(
relname_text
))));
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* There should be at least one key attribute
*/
if
(
pknumatts
=
=
0
)
if
(
pknumatts
_tmp
<
=
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"number of key attributes must be > 0"
)));
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* Target array is made up of key values that will be used to build the
* SQL string for use on the remote system.
*/
tgt_ndim
=
ARR_NDIM
(
tgt_pkattvals_arry
);
tgt_dim
=
ARR_DIMS
(
tgt_pkattvals_arry
);
tgt_nitems
=
ArrayGetNItems
(
tgt_ndim
,
tgt_dim
);
tgt_pkattvals
=
get_text_array_contents
(
tgt_pkattvals_arry
,
&
tgt_nitems
);
/*
* There should be one target array key value for each key attnum
...
...
@@ -1338,22 +1272,6 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
errmsg
(
"target key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input target array
*/
Assert
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
tgt_pkattvals
=
(
char
**
)
palloc
(
tgt_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
tgt_pkattvals_arry
);
for
(
i
=
0
;
i
<
tgt_nitems
;
i
++
)
{
tgt_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Prep work is finally done. Go get the SQL string.
*/
...
...
@@ -1389,29 +1307,18 @@ PG_FUNCTION_INFO_V1(dblink_build_sql_update);
Datum
dblink_build_sql_update
(
PG_FUNCTION_ARGS
)
{
text
*
relname_text
=
PG_GETARG_TEXT_P
(
0
);
int2vector
*
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
int32
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
ArrayType
*
src_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
ArrayType
*
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
4
);
Oid
relid
;
text
*
relname_text
;
int2vector
*
pkattnums
;
int
pknumatts_tmp
;
int16
pknumatts
=
0
;
char
**
src_pkattvals
;
char
**
tgt_pkattvals
;
ArrayType
*
src_pkattvals_arry
;
ArrayType
*
tgt_pkattvals_arry
;
int
src_ndim
;
int
*
src_dim
;
int
src_nitems
;
int
tgt_ndim
;
int
*
tgt_dim
;
int
tgt_nitems
;
int
i
;
char
*
ptr
;
char
*
sql
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
relname_text
=
PG_GETARG_TEXT_P
(
0
);
/*
* Convert relname to rel OID.
...
...
@@ -1423,34 +1330,27 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
errmsg
(
"relation
\"
%s
\"
does not exist"
,
GET_STR
(
relname_text
))));
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* There should be one source array key values for each key attnum
*/
if
(
pknumatts
=
=
0
)
if
(
pknumatts
_tmp
<
=
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"number of key attributes must be > 0"
)));
src_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
4
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* Source array is made up of key values that will be used to locate the
* tuple of interest from the local system.
*/
src_ndim
=
ARR_NDIM
(
src_pkattvals_arry
);
src_dim
=
ARR_DIMS
(
src_pkattvals_arry
);
src_nitems
=
ArrayGetNItems
(
src_ndim
,
src_dim
);
src_pkattvals
=
get_text_array_contents
(
src_pkattvals_arry
,
&
src_nitems
);
/*
* There should be one source array key value for each key attnum
...
...
@@ -1461,29 +1361,11 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
errmsg
(
"source key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input source array
*/
Assert
(
ARR_ELEMTYPE
(
src_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
src_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
src_pkattvals
=
(
char
**
)
palloc
(
src_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
src_pkattvals_arry
);
for
(
i
=
0
;
i
<
src_nitems
;
i
++
)
{
src_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Target array is made up of key values that will be used to build the
* SQL string for use on the remote system.
*/
tgt_ndim
=
ARR_NDIM
(
tgt_pkattvals_arry
);
tgt_dim
=
ARR_DIMS
(
tgt_pkattvals_arry
);
tgt_nitems
=
ArrayGetNItems
(
tgt_ndim
,
tgt_dim
);
tgt_pkattvals
=
get_text_array_contents
(
tgt_pkattvals_arry
,
&
tgt_nitems
);
/*
* There should be one target array key value for each key attnum
...
...
@@ -1494,22 +1376,6 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
errmsg
(
"target key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input target array
*/
Assert
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
tgt_pkattvals
=
(
char
**
)
palloc
(
tgt_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
tgt_pkattvals_arry
);
for
(
i
=
0
;
i
<
tgt_nitems
;
i
++
)
{
tgt_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Prep work is finally done. Go get the SQL string.
*/
...
...
@@ -1598,6 +1464,67 @@ get_pkey_attnames(Oid relid, int16 *numatts)
return
result
;
}
/*
* Deconstruct a text[] into C-strings (note any NULL elements will be
* returned as NULL pointers)
*/
static
char
**
get_text_array_contents
(
ArrayType
*
array
,
int
*
numitems
)
{
int
ndim
=
ARR_NDIM
(
array
);
int
*
dims
=
ARR_DIMS
(
array
);
int
nitems
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
char
**
values
;
char
*
ptr
;
bits8
*
bitmap
;
int
bitmask
;
int
i
;
Assert
(
ARR_ELEMTYPE
(
array
)
==
TEXTOID
);
*
numitems
=
nitems
=
ArrayGetNItems
(
ndim
,
dims
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
array
),
&
typlen
,
&
typbyval
,
&
typalign
);
values
=
(
char
**
)
palloc
(
nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
array
);
bitmap
=
ARR_NULLBITMAP
(
array
);
bitmask
=
1
;
for
(
i
=
0
;
i
<
nitems
;
i
++
)
{
if
(
bitmap
&&
(
*
bitmap
&
bitmask
)
==
0
)
{
values
[
i
]
=
NULL
;
}
else
{
values
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/* advance bitmap pointer if any */
if
(
bitmap
)
{
bitmask
<<=
1
;
if
(
bitmask
==
0x100
)
{
bitmap
++
;
bitmask
=
1
;
}
}
}
return
values
;
}
static
char
*
get_sql_insert
(
Oid
relid
,
int2vector
*
pkattnums
,
int16
pknumatts
,
char
**
src_pkattvals
,
char
**
tgt_pkattvals
)
{
...
...
@@ -1665,7 +1592,7 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
key
=
-
1
;
if
(
key
>
-
1
)
val
=
pstrdup
(
tgt_pkattvals
[
key
])
;
val
=
tgt_pkattvals
[
key
]
?
pstrdup
(
tgt_pkattvals
[
key
])
:
NULL
;
else
val
=
SPI_getvalue
(
tuple
,
tupdesc
,
i
+
1
);
...
...
@@ -1697,7 +1624,6 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
int
natts
;
StringInfo
str
=
makeStringInfo
();
char
*
sql
;
char
*
val
=
NULL
;
int
i
;
/* get relation name including any needed schema prefix and quoting */
...
...
@@ -1721,17 +1647,13 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
appendStringInfo
(
str
,
"%s"
,
quote_ident_cstr
(
NameStr
(
tupdesc
->
attrs
[
pkattnum
-
1
]
->
attname
)));
if
(
tgt_pkattvals
!=
NULL
)
val
=
pstrdup
(
tgt_pkattvals
[
i
]);
else
if
(
tgt_pkattvals
==
NULL
)
/* internal error */
elog
(
ERROR
,
"target key array must not be NULL"
);
if
(
val
!=
NULL
)
{
appendStringInfo
(
str
,
" = %s"
,
quote_literal_cstr
(
val
));
pfree
(
val
);
}
if
(
tgt_pkattvals
[
i
]
!=
NULL
)
appendStringInfo
(
str
,
" = %s"
,
quote_literal_cstr
(
tgt_pkattvals
[
i
]));
else
appendStringInfo
(
str
,
" IS NULL"
);
}
...
...
@@ -1795,7 +1717,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
key
=
-
1
;
if
(
key
>
-
1
)
val
=
pstrdup
(
tgt_pkattvals
[
key
])
;
val
=
tgt_pkattvals
[
key
]
?
pstrdup
(
tgt_pkattvals
[
key
])
:
NULL
;
else
val
=
SPI_getvalue
(
tuple
,
tupdesc
,
i
+
1
);
...
...
@@ -1822,7 +1744,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
quote_ident_cstr
(
NameStr
(
tupdesc
->
attrs
[
pkattnum
-
1
]
->
attname
)));
if
(
tgt_pkattvals
!=
NULL
)
val
=
pstrdup
(
tgt_pkattvals
[
i
])
;
val
=
tgt_pkattvals
[
i
]
?
pstrdup
(
tgt_pkattvals
[
i
])
:
NULL
;
else
val
=
SPI_getvalue
(
tuple
,
tupdesc
,
pkattnum
);
...
...
@@ -1905,7 +1827,6 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
int
ret
;
HeapTuple
tuple
;
int
i
;
char
*
val
=
NULL
;
/* get relation name including any needed schema prefix and quoting */
relname
=
generate_relation_name
(
relid
);
...
...
@@ -1940,12 +1861,9 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
appendStringInfo
(
str
,
"%s"
,
quote_ident_cstr
(
NameStr
(
tupdesc
->
attrs
[
pkattnum
-
1
]
->
attname
)));
val
=
pstrdup
(
src_pkattvals
[
i
]);
if
(
val
!=
NULL
)
{
appendStringInfo
(
str
,
" = %s"
,
quote_literal_cstr
(
val
));
pfree
(
val
);
}
if
(
src_pkattvals
[
i
]
!=
NULL
)
appendStringInfo
(
str
,
" = %s"
,
quote_literal_cstr
(
src_pkattvals
[
i
]));
else
appendStringInfo
(
str
,
" IS NULL"
);
}
...
...
contrib/tsearch2/rank.c
View file @
1d0d8d3c
...
...
@@ -3,20 +3,20 @@
* Teodor Sigaev <teodor@sigaev.ru>
*/
#include "postgres.h"
#include <math.h>
#include "access/gist.h"
#include "access/itup.h"
#include "utils/builtins.h"
#include "catalog/namespace.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "fmgr.h"
#include "funcapi.h"
#include "storage/bufpage.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "nodes/pg_list.h"
#include "catalog/namespace.h"
#include "storage/bufpage.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "tsvector.h"
#include "query.h"
...
...
@@ -354,6 +354,7 @@ rank(PG_FUNCTION_ARGS)
int
method
=
DEF_NORM_METHOD
;
float
res
=
0
.
0
;
float
ws
[
lengthof
(
weights
)];
float4
*
arrdata
;
int
i
;
if
(
ARR_NDIM
(
win
)
!=
1
)
...
...
@@ -366,9 +367,15 @@ rank(PG_FUNCTION_ARGS)
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"array of weight is too short"
)));
if
(
ARR_HASNULL
(
win
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"array of weight must not contain nulls"
)));
arrdata
=
(
float4
*
)
ARR_DATA_PTR
(
win
);
for
(
i
=
0
;
i
<
lengthof
(
weights
);
i
++
)
{
ws
[
i
]
=
(
((
float4
*
)
ARR_DATA_PTR
(
win
))[
i
]
>=
0
)
?
((
float4
*
)
ARR_DATA_PTR
(
win
))
[
i
]
:
weights
[
i
];
ws
[
i
]
=
(
arrdata
[
i
]
>=
0
)
?
arrdata
[
i
]
:
weights
[
i
];
if
(
ws
[
i
]
>
1
.
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
...
...
contrib/tsearch2/snowball/header.h
View file @
1d0d8d3c
...
...
@@ -3,9 +3,6 @@
#include "api.h"
#define MAXINT INT_MAX
#define MININT INT_MIN
#define HEAD 2*sizeof(int)
#define SIZE(p) ((int *)(p))[-1]
...
...
contrib/tsearch2/ts_cfg.c
View file @
1d0d8d3c
...
...
@@ -113,6 +113,8 @@ init_cfg(Oid id, TSCfgInfo * cfg)
ts_error
(
ERROR
,
"Wrong dimension"
);
if
(
ARRNELEMS
(
a
)
<
1
)
continue
;
if
(
ARR_HASNULL
(
a
))
ts_error
(
ERROR
,
"Array must not contain nulls"
);
cfg
->
map
[
lexid
].
len
=
ARRNELEMS
(
a
);
cfg
->
map
[
lexid
].
dict_id
=
(
Datum
*
)
malloc
(
sizeof
(
Datum
)
*
cfg
->
map
[
lexid
].
len
);
...
...
src/backend/utils/adt/acl.c
View file @
1d0d8d3c
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.12
8 2005/11/17 22:14:52
tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.12
9 2005/11/18 02:38:23
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -67,6 +67,7 @@ static List *cached_membership_roles = NIL;
static
const
char
*
getid
(
const
char
*
s
,
char
*
n
);
static
void
putid
(
char
*
p
,
const
char
*
s
);
static
Acl
*
allocacl
(
int
n
);
static
void
check_acl
(
const
Acl
*
acl
);
static
const
char
*
aclparse
(
const
char
*
s
,
AclItem
*
aip
);
static
bool
aclitem_match
(
const
AclItem
*
a1
,
const
AclItem
*
a2
);
static
void
check_circularity
(
const
Acl
*
old_acl
,
const
AclItem
*
mod_aip
,
...
...
@@ -359,6 +360,26 @@ allocacl(int n)
return
new_acl
;
}
/*
* Verify that an ACL array is acceptable (one-dimensional and has no nulls)
*/
static
void
check_acl
(
const
Acl
*
acl
)
{
if
(
ARR_ELEMTYPE
(
acl
)
!=
ACLITEMOID
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"ACL array contains wrong datatype"
)));
if
(
ARR_NDIM
(
acl
)
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"ACL arrays must be one-dimensional"
)));
if
(
ARR_HASNULL
(
acl
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"ACL arrays must not contain nulls"
)));
}
/*
* aclitemin
* Allocates storage for, and fills in, a new AclItem given a string
...
...
@@ -612,15 +633,8 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
int
dst
,
num
;
/* These checks for null input are probably dead code, but... */
if
(
!
old_acl
||
ACL_NUM
(
old_acl
)
<
0
)
old_acl
=
allocacl
(
0
);
if
(
!
mod_aip
)
{
new_acl
=
allocacl
(
ACL_NUM
(
old_acl
));
memcpy
(
new_acl
,
old_acl
,
ACL_SIZE
(
old_acl
));
return
new_acl
;
}
/* Caller probably already checked old_acl, but be safe */
check_acl
(
old_acl
);
/* If granting grant options, check for circularity */
if
(
modechg
!=
ACL_MODECHG_DEL
&&
...
...
@@ -740,6 +754,8 @@ aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
targ
,
num
;
check_acl
(
old_acl
);
/*
* Make a copy of the given ACL, substituting new owner ID for old
* wherever it appears as either grantor or grantee. Also note if the new
...
...
@@ -836,6 +852,8 @@ check_circularity(const Acl *old_acl, const AclItem *mod_aip,
num
;
AclMode
own_privs
;
check_acl
(
old_acl
);
/*
* For now, grant options can only be granted to roles, not PUBLIC.
* Otherwise we'd have to work a bit harder here.
...
...
@@ -916,6 +934,8 @@ recursive_revoke(Acl *acl,
int
i
,
num
;
check_acl
(
acl
);
/* The owner can never truly lose grant options, so short-circuit */
if
(
grantee
==
ownerId
)
return
acl
;
...
...
@@ -1005,6 +1025,8 @@ aclmask(const Acl *acl, Oid roleid, Oid ownerId,
if
(
acl
==
NULL
)
elog
(
ERROR
,
"null ACL"
);
check_acl
(
acl
);
/* Quick exit for mask == 0 */
if
(
mask
==
0
)
return
0
;
...
...
@@ -1091,6 +1113,8 @@ aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId,
if
(
acl
==
NULL
)
elog
(
ERROR
,
"null ACL"
);
check_acl
(
acl
);
/* Quick exit for mask == 0 */
if
(
mask
==
0
)
return
0
;
...
...
@@ -1151,6 +1175,8 @@ aclmembers(const Acl *acl, Oid **roleids)
return
0
;
}
check_acl
(
acl
);
/* Allocate the worst-case space requirement */
list
=
palloc
(
ACL_NUM
(
acl
)
*
2
*
sizeof
(
Oid
));
acldat
=
ACL_DAT
(
acl
);
...
...
@@ -1240,6 +1266,7 @@ aclcontains(PG_FUNCTION_ARGS)
int
i
,
num
;
check_acl
(
acl
);
num
=
ACL_NUM
(
acl
);
aidat
=
ACL_DAT
(
acl
);
for
(
i
=
0
;
i
<
num
;
++
i
)
...
...
src/backend/utils/adt/varlena.c
View file @
1d0d8d3c
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.1
39 2005/10/29 00:31:51 petere
Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.1
40 2005/11/18 02:38:23 tgl
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -2491,16 +2491,18 @@ array_to_text(PG_FUNCTION_ARGS)
int
nitems
,
*
dims
,
ndims
;
char
*
p
;
Oid
element_type
;
int
typlen
;
bool
typbyval
;
char
typalign
;
StringInfo
result_str
=
makeStringInfo
();
bool
printed
=
false
;
char
*
p
;
bits8
*
bitmap
;
int
bitmask
;
int
i
;
ArrayMetaState
*
my_extra
;
p
=
ARR_DATA_PTR
(
v
);
ndims
=
ARR_NDIM
(
v
);
dims
=
ARR_DIMS
(
v
);
nitems
=
ArrayGetNItems
(
ndims
,
dims
);
...
...
@@ -2522,7 +2524,7 @@ array_to_text(PG_FUNCTION_ARGS)
fcinfo
->
flinfo
->
fn_extra
=
MemoryContextAlloc
(
fcinfo
->
flinfo
->
fn_mcxt
,
sizeof
(
ArrayMetaState
));
my_extra
=
(
ArrayMetaState
*
)
fcinfo
->
flinfo
->
fn_extra
;
my_extra
->
element_type
=
InvalidOid
;
my_extra
->
element_type
=
~
element_type
;
}
if
(
my_extra
->
element_type
!=
element_type
)
...
...
@@ -2542,25 +2544,49 @@ array_to_text(PG_FUNCTION_ARGS)
typbyval
=
my_extra
->
typbyval
;
typalign
=
my_extra
->
typalign
;
p
=
ARR_DATA_PTR
(
v
);
bitmap
=
ARR_NULLBITMAP
(
v
);
bitmask
=
1
;
for
(
i
=
0
;
i
<
nitems
;
i
++
)
{
Datum
itemvalue
;
char
*
value
;
/* Get source element, checking for NULL */
if
(
bitmap
&&
(
*
bitmap
&
bitmask
)
==
0
)
{
/* we ignore nulls */
}
else
{
itemvalue
=
fetch_att
(
p
,
typbyval
,
typlen
);
value
=
DatumGetCString
(
FunctionCall1
(
&
my_extra
->
proc
,
itemvalue
));
if
(
i
>
0
)
if
(
printed
)
appendStringInfo
(
result_str
,
"%s%s"
,
fldsep
,
value
);
else
appendStringInfoString
(
result_str
,
value
);
printed
=
true
;
p
=
att_addlength
(
p
,
typlen
,
PointerGetDatum
(
p
));
p
=
(
char
*
)
att_align
(
p
,
typalign
);
}
/* advance bitmap pointer if any */
if
(
bitmap
)
{
bitmask
<<=
1
;
if
(
bitmask
==
0x100
)
{
bitmap
++
;
bitmask
=
1
;
}
}
}
PG_RETURN_TEXT_P
(
PG_STR_GET_TEXT
(
result_str
->
data
));
}
...
...
src/include/utils/acl.h
View file @
1d0d8d3c
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.8
7 2005/11/17 22:14:55
tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.8
8 2005/11/18 02:38:24
tgl Exp $
*
* NOTES
* An ACL array is simply an array of AclItems, representing the union
...
...
@@ -78,9 +78,9 @@ typedef struct AclItem
#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFF << 16)
/*
* Definitions for convenient access to Acl (array of AclItem)
and IdList
*
(array of Oid). These are standard PostgreSQL arrays, but are restricted
*
to have one dimension
. We also ignore the lower bound when reading,
* Definitions for convenient access to Acl (array of AclItem)
.
*
These are standard PostgreSQL arrays, but are restricted to have one
*
dimension and no nulls
. We also ignore the lower bound when reading,
* and set it to one when writing.
*
* CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all
...
...
@@ -100,16 +100,6 @@ typedef ArrayType Acl;
#define ACL_N_SIZE(N) (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem)))
#define ACL_SIZE(ACL) ARR_SIZE(ACL)
/*
* IdList a one-dimensional array of Oid
*/
typedef
ArrayType
IdList
;
#define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0])
#define IDLIST_DAT(IDL) ((Oid *) ARR_DATA_PTR(IDL))
#define IDLIST_N_SIZE(N) (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(Oid)))
#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
/*
* fmgr macros for these types
*/
...
...
@@ -123,13 +113,6 @@ typedef ArrayType IdList;
#define PG_GETARG_ACL_P_COPY(n) DatumGetAclPCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_ACL_P(x) PG_RETURN_POINTER(x)
#define DatumGetIdListP(X) ((IdList *) PG_DETOAST_DATUM(X))
#define DatumGetIdListPCopy(X) ((IdList *) PG_DETOAST_DATUM_COPY(X))
#define PG_GETARG_IDLIST_P(n) DatumGetIdListP(PG_GETARG_DATUM(n))
#define PG_GETARG_IDLIST_P_COPY(n) DatumGetIdListPCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_IDLIST_P(x) PG_RETURN_POINTER(x)
/*
* ACL modification opcodes for aclupdate
*/
...
...
src/pl/plpgsql/src/pl_exec.c
View file @
1d0d8d3c
...
...
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.15
5 2005/11/17 22:14:55
tgl Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.15
6 2005/11/18 02:38:24
tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
...
...
@@ -3241,8 +3241,7 @@ exec_assign_value(PLpgSQL_execstate * estate,
int
i
;
PLpgSQL_expr
*
subscripts
[
MAXDIM
];
int
subscriptvals
[
MAXDIM
];
bool
havenullsubscript
,
oldarrayisnull
;
bool
oldarrayisnull
;
Oid
arraytypeid
,
arrayelemtypeid
;
int16
arraytyplen
,
...
...
@@ -3295,9 +3294,9 @@ exec_assign_value(PLpgSQL_execstate * estate,
arraytyplen
=
get_typlen
(
arraytypeid
);
/*
* Evaluate the subscripts, switch into left-to-right order
* Evaluate the subscripts, switch into left-to-right order.
* Like ExecEvalArrayRef(), complain if any subscript is null.
*/
havenullsubscript
=
false
;
for
(
i
=
0
;
i
<
nsubscripts
;
i
++
)
{
bool
subisnull
;
...
...
@@ -3306,43 +3305,39 @@ exec_assign_value(PLpgSQL_execstate * estate,
exec_eval_integer
(
estate
,
subscripts
[
nsubscripts
-
1
-
i
],
&
subisnull
);
havenullsubscript
|=
subisnull
;
if
(
subisnull
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"array subscript in assignment must not be NULL"
)));
}
/*
* Skip the assignment if we have any nulls in the subscripts
* or the righthand side. This is pretty bogus but it
* corresponds to the current behavior of ExecEvalArrayRef().
*/
if
(
havenullsubscript
||
*
isNull
)
return
;
/* Coerce source value to match array element type. */
coerced_value
=
exec_simple_cast_value
(
value
,
valtype
,
arrayelemtypeid
,
-
1
,
*
isNull
);
/*
* If the original array is null, cons up an empty array so
* that the assignment can proceed; we'll end with a
* one-element array containing just the assigned-to
* subscript. This only works for varlena arrays, though; for
* fixed-length array types we skip the assignment. Again,
* this corresponds to the current behavior of
* fixed-length array types we skip the assignment. We can't
* support assignment of a null entry into a fixed-length
* array, either, so that's a no-op too. This is all ugly
* but corresponds to the current behavior of
* ExecEvalArrayRef().
*/
if
(
oldarrayisnull
)
{
if
(
arraytyplen
>
0
)
/* fixed-length array? */
if
(
arraytyplen
>
0
&&
/* fixed-length array? */
(
oldarrayisnull
||
*
isNull
))
return
;
if
(
oldarrayisnull
)
oldarrayval
=
construct_empty_array
(
arrayelemtypeid
);
}
else
oldarrayval
=
(
ArrayType
*
)
DatumGetPointer
(
oldarraydatum
);
/* Coerce source value to match array element type. */
coerced_value
=
exec_simple_cast_value
(
value
,
valtype
,
arrayelemtypeid
,
-
1
,
*
isNull
);
/*
* Build the modified array value.
*/
...
...
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