Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
5eb17f53
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5eb17f53
编写于
7月 31, 1996
作者:
M
Marc G. Fournier
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Moved src/extend to contrib
上级
c6cf2182
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
0 addition
and
1267 deletion
+0
-1267
src/extend/array/array_iterator.c
src/extend/array/array_iterator.c
+0
-251
src/extend/array/array_iterator.doc
src/extend/array/array_iterator.doc
+0
-26
src/extend/array/array_iterator.sql
src/extend/array/array_iterator.sql
+0
-137
src/extend/datetime/datetime_functions.c
src/extend/datetime/datetime_functions.c
+0
-147
src/extend/datetime/datetime_functions.doc
src/extend/datetime/datetime_functions.doc
+0
-25
src/extend/datetime/datetime_functions.sql
src/extend/datetime/datetime_functions.sql
+0
-69
src/extend/soundex/soundex.c
src/extend/soundex/soundex.c
+0
-83
src/extend/soundex/soundex.sql
src/extend/soundex/soundex.sql
+0
-57
src/extend/string/string_io.c
src/extend/string/string_io.c
+0
-361
src/extend/string/string_io.sql
src/extend/string/string_io.sql
+0
-111
未找到文件。
src/extend/array/array_iterator.c
已删除
100644 → 0
浏览文件 @
c6cf2182
/*
* array_iterator.c --
*
* This file defines a new group of operators which take an
* array and a scalar value, iterate a scalar operator over the
* elements of the array and the value and compute a result as
* the logical OR or AND of the results.
* For example array_int4eq returns true if some of the elements
* of an array of int4 is equal to the given value:
*
* array_int4eq({1,2,3}, 1) --> true
* array_int4eq({1,2,3}, 4) --> false
*
* If we have defined T array types and O scalar operators
* we can define T x O array operators, each of them has a name
* like "array_<basetype><operation>" and takes an array of type T
* iterating the operator O over all the elements. Note however
* that some of the possible combination are invalid, for example
* the array_int4_like because there is no like operator for int4.
* It is now possible to write queries which look inside the arrays:
*
* create table t(id int4[], txt text[]);
* select * from t where t.id *= 123;
* select * from t where t.txt *~ '[a-z]';
* select * from t where t.txt[1:3] **~ '[a-z]';
*
* Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it>
*/
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "postgres.h"
#include "pg_type.h"
#include "miscadmin.h"
#include "syscache.h"
#include "access/xact.h"
#include "utils/builtins.h"
#include "utils/elog.h"
static
int32
array_iterator
(
Oid
elemtype
,
Oid
proc
,
int
and
,
ArrayType
*
array
,
Datum
value
)
{
HeapTuple
typ_tuple
;
TypeTupleForm
typ_struct
;
bool
typbyval
;
int
typlen
;
func_ptr
proc_fn
;
int
pronargs
;
int
nitems
,
i
,
result
;
int
ndim
,
*
dim
;
char
*
p
;
/* Sanity checks */
if
((
array
==
(
ArrayType
*
)
NULL
)
||
(
ARR_IS_LO
(
array
)
==
true
))
{
/* elog(NOTICE, "array_iterator: array is null"); */
return
(
0
);
}
ndim
=
ARR_NDIM
(
array
);
dim
=
ARR_DIMS
(
array
);
nitems
=
getNitems
(
ndim
,
dim
);
if
(
nitems
==
0
)
{
/* elog(NOTICE, "array_iterator: nitems = 0"); */
return
(
0
);
}
/* Lookup element type information */
typ_tuple
=
SearchSysCacheTuple
(
TYPOID
,
ObjectIdGetDatum
(
elemtype
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
typ_tuple
))
{
elog
(
WARN
,
"array_iterator: cache lookup failed for type %d"
,
elemtype
);
return
0
;
}
typ_struct
=
(
TypeTupleForm
)
GETSTRUCT
(
typ_tuple
);
typlen
=
typ_struct
->
typlen
;
typbyval
=
typ_struct
->
typbyval
;
/* Lookup the function entry point */
proc_fn
==
(
func_ptr
)
NULL
;
fmgr_info
(
proc
,
&
proc_fn
,
&
pronargs
);
if
((
proc_fn
==
NULL
)
||
(
pronargs
!=
2
))
{
elog
(
WARN
,
"array_iterator: fmgr_info lookup failed for oid %d"
,
proc
);
return
(
0
);
}
/* Scan the array and apply the operator to each element */
result
=
0
;
p
=
ARR_DATA_PTR
(
array
);
for
(
i
=
0
;
i
<
nitems
;
i
++
)
{
if
(
typbyval
)
{
switch
(
typlen
)
{
case
1
:
result
=
(
int
)
(
*
proc_fn
)(
*
p
,
value
);
break
;
case
2
:
result
=
(
int
)
(
*
proc_fn
)(
*
(
int16
*
)
p
,
value
);
break
;
case
3
:
case
4
:
result
=
(
int
)
(
*
proc_fn
)(
*
(
int32
*
)
p
,
value
);
break
;
}
p
+=
typlen
;
}
else
{
result
=
(
int
)
(
*
proc_fn
)(
p
,
value
);
if
(
typlen
>
0
)
{
p
+=
typlen
;
}
else
{
p
+=
INTALIGN
(
*
(
int32
*
)
p
);
}
}
if
(
result
)
{
if
(
!
and
)
{
return
(
1
);
}
}
else
{
if
(
and
)
{
return
(
0
);
}
}
}
if
(
and
&&
result
)
{
return
(
1
);
}
else
{
return
(
0
);
}
}
/*
* Iterators for type _text
*/
int32
array_texteq
(
ArrayType
*
array
,
char
*
value
)
{
return
array_iterator
((
Oid
)
25
,
/* text */
(
Oid
)
67
,
/* texteq */
0
,
/* logical or */
array
,
(
Datum
)
value
);
}
int32
array_all_texteq
(
ArrayType
*
array
,
char
*
value
)
{
return
array_iterator
((
Oid
)
25
,
/* text */
(
Oid
)
67
,
/* texteq */
1
,
/* logical and */
array
,
(
Datum
)
value
);
}
int32
array_textregexeq
(
ArrayType
*
array
,
char
*
value
)
{
return
array_iterator
((
Oid
)
25
,
/* text */
(
Oid
)
81
,
/* textregexeq */
0
,
/* logical or */
array
,
(
Datum
)
value
);
}
int32
array_all_textregexeq
(
ArrayType
*
array
,
char
*
value
)
{
return
array_iterator
((
Oid
)
25
,
/* text */
(
Oid
)
81
,
/* textregexeq */
1
,
/* logical and */
array
,
(
Datum
)
value
);
}
/*
* Iterators for type _char16. Note that the regexp operators
* take the second argument of type text.
*/
int32
array_char16eq
(
ArrayType
*
array
,
char
*
value
)
{
return
array_iterator
((
Oid
)
20
,
/* char16 */
(
Oid
)
490
,
/* char16eq */
0
,
/* logical or */
array
,
(
Datum
)
value
);
}
int32
array_all_char16eq
(
ArrayType
*
array
,
char
*
value
)
{
return
array_iterator
((
Oid
)
20
,
/* char16 */
(
Oid
)
490
,
/* char16eq */
1
,
/* logical and */
array
,
(
Datum
)
value
);
}
int32
array_char16regexeq
(
ArrayType
*
array
,
char
*
value
)
{
return
array_iterator
((
Oid
)
20
,
/* char16 */
(
Oid
)
700
,
/* char16regexeq */
0
,
/* logical or */
array
,
(
Datum
)
value
);
}
int32
array_all_char16regexeq
(
ArrayType
*
array
,
char
*
value
)
{
return
array_iterator
((
Oid
)
20
,
/* char16 */
(
Oid
)
700
,
/* char16regexeq */
1
,
/* logical and */
array
,
(
Datum
)
value
);
}
/*
* Iterators for type _int4
*/
int32
array_int4eq
(
ArrayType
*
array
,
int4
value
)
{
return
array_iterator
((
Oid
)
23
,
/* int4 */
(
Oid
)
65
,
/* int4eq */
0
,
/* logical or */
array
,
(
Datum
)
value
);
}
int32
array_all_int4eq
(
ArrayType
*
array
,
int4
value
)
{
return
array_iterator
((
Oid
)
23
,
/* int4 */
(
Oid
)
65
,
/* int4eq */
1
,
/* logical and */
array
,
(
Datum
)
value
);
}
int32
array_int4gt
(
ArrayType
*
array
,
int4
value
)
{
return
array_iterator
((
Oid
)
23
,
/* int4 */
(
Oid
)
147
,
/* int4gt */
0
,
/* logical or */
array
,
(
Datum
)
value
);
}
int32
array_all_int4gt
(
ArrayType
*
array
,
int4
value
)
{
return
array_iterator
((
Oid
)
23
,
/* int4 */
(
Oid
)
147
,
/* int4gt */
1
,
/* logical and */
array
,
(
Datum
)
value
);
}
src/extend/array/array_iterator.doc
已删除
100644 → 0
浏览文件 @
c6cf2182
From: Massimo Dal Zotto <dz@cs.unitn.it>
Date: Mon, 6 May 1996 01:03:37 +0200 (MET DST)
Subject: [PG95]: new operators for arrays
- -----BEGIN PGP SIGNED MESSAGE-----
Hi,
I have written an extension to Postgres95 which allows to use qualification
clauses based on the values of single elements of arrays.
For example I can now select rows having some or all element of an array
attribute equal to a given value or matching a regular expression:
select * from t where t.foo *= 'bar';
select * from t where t.foo **~ '^ba[rz]';
The scheme is quite general, each operator which operates on a base type can
be iterated over the elements of an array. It seem to work well but defining
each new operators requires writing a different C function. Furthermore in
each function there are two hardcoded OIDs which reference a base type and
a procedure. Not very portable. Can anyone suggest a better and more portable
way to do it ? Do you think this could be a useful feature for next release ?
Here is my code, it can be compiled and loaded as a dynamic module without
need to recompile the backend. I have defined only the few operators I needed,
the list can be extended. Feddback is welcome.
src/extend/array/array_iterator.sql
已删除
100644 → 0
浏览文件 @
c6cf2182
/*
* SQL code
- - -- load the new functions
- - --
load '/home/dz/lib/postgres/array_iterator.so';
- - -- define the array operators *=, **=, *~ and **~ for type _text
- - --
create function array_texteq(_text, text)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_all_texteq(_text, text)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_textregexeq(_text, text)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_all_textregexeq(_text, text)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create operator *= (
leftarg=_text,
rightarg=text,
procedure=array_texteq);
create operator **= (
leftarg=_text,
rightarg=text,
procedure=array_all_texteq);
create operator *~ (
leftarg=_text,
rightarg=text,
procedure=array_textregexeq);
create operator **~ (
leftarg=_text,
rightarg=text,
procedure=array_all_textregexeq);
- - -- define the array operators *=, **=, *~ and **~ for type _char16
- - --
create function array_char16eq(_char16, char16)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_all_char16eq(_char16, char16)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_char16regexeq(_char16, text)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_all_char16regexeq(_char16, text)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create operator *= (
leftarg=_char16,
rightarg=char16,
procedure=array_char16eq);
create operator **= (
leftarg=_char16,
rightarg=char16,
procedure=array_all_char16eq);
create operator *~ (
leftarg=_char16,
rightarg=text,
procedure=array_char16regexeq);
create operator **~ (
leftarg=_char16,
rightarg=text,
procedure=array_all_char16regexeq);
- - -- define the array operators *=, **=, *> and **> for type _int4
- - --
create function array_int4eq(_int4, int4)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_all_int4eq(_int4, int4)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_int4gt(_int4, int4)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create function array_all_int4gt(_int4, int4)
returns bool
as '/home/dz/lib/postgres/array_iterator.so'
language 'c';
create operator *= (
leftarg=_int4,
rightarg=int4,
procedure=array_int4eq);
create operator **= (
leftarg=_int4,
rightarg=int4,
procedure=array_all_int4eq);
create operator *> (
leftarg=_int4,
rightarg=int4,
procedure=array_int4gt);
create operator **> (
leftarg=_int4,
rightarg=int4,
procedure=array_all_int4gt);
*/
/* end of file */
src/extend/datetime/datetime_functions.c
已删除
100644 → 0
浏览文件 @
c6cf2182
/*
* datetime_functions.c --
*
* This file defines new functions for the time and date data types.
*
* Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it>
*/
#include <time.h>
#include "postgres.h"
#include "pg_type.h"
#include "utils/palloc.h"
typedef
struct
DateADT
{
char
day
;
char
month
;
short
year
;
}
DateADT
;
typedef
struct
TimeADT
{
short
hr
;
short
min
;
float
sec
;
}
TimeADT
;
TimeADT
*
time_difference
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
TimeADT
*
time
=
(
TimeADT
*
)
palloc
(
sizeof
(
TimeADT
));
time
->
sec
=
time1
->
sec
-
time2
->
sec
;
time
->
min
=
time1
->
min
-
time2
->
min
;
time
->
hr
=
time1
->
hr
-
time2
->
hr
;
if
(
time
->
sec
<
0
)
{
time
->
sec
+=
60
.
0
;
time
->
min
--
;
}
else
if
(
time
->
sec
>=
60
.
0
)
{
time
->
sec
-=
60
.
0
;
time
->
min
++
;
}
if
(
time
->
min
<
0
)
{
time
->
min
+=
60
;
time
->
hr
--
;
}
else
if
(
time
->
min
>=
60
)
{
time
->
min
-=
60
;
time
->
hr
++
;
}
if
(
time
->
hr
<
0
)
{
time
->
hr
+=
24
;
}
else
if
(
time
->
hr
>=
24
)
{
time
->
hr
-=
24
;
}
return
(
time
);
}
TimeADT
*
currentTime
()
{
time_t
current_time
;
struct
tm
*
tm
;
TimeADT
*
result
=
(
TimeADT
*
)
palloc
(
sizeof
(
TimeADT
));
current_time
=
time
(
NULL
);
tm
=
localtime
(
&
current_time
);
result
->
sec
=
tm
->
tm_sec
;
result
->
min
=
tm
->
tm_min
;
result
->
hr
=
tm
->
tm_hour
;
return
(
result
);
}
int4
currentDate
()
{
time_t
current_time
;
struct
tm
*
tm
;
int4
result
;
DateADT
*
date
=
(
DateADT
*
)
&
result
;
current_time
=
time
(
NULL
);
tm
=
localtime
(
&
current_time
);
date
->
day
=
tm
->
tm_mday
;
date
->
month
=
tm
->
tm_mon
+
1
;
date
->
year
=
tm
->
tm_year
+
1900
;
return
(
result
);
}
int4
hours
(
TimeADT
*
time
)
{
return
(
time
->
hr
);
}
int4
minutes
(
TimeADT
*
time
)
{
return
(
time
->
min
);
}
int4
seconds
(
TimeADT
*
time
)
{
int
seconds
=
(
int
)
time
->
sec
;
return
(
seconds
);
}
int4
day
(
int4
val
)
{
DateADT
*
date
=
(
DateADT
*
)
&
val
;
return
(
date
->
day
);
}
int4
month
(
int4
val
)
{
DateADT
*
date
=
(
DateADT
*
)
&
val
;
return
(
date
->
month
);
}
int4
year
(
int4
val
)
{
DateADT
*
date
=
(
DateADT
*
)
&
val
;
return
(
date
->
year
);
}
int4
asMinutes
(
TimeADT
*
time
)
{
int
seconds
=
(
int
)
time
->
sec
;
return
(
time
->
min
+
60
*
time
->
hr
);
}
int4
asSeconds
(
TimeADT
*
time
)
{
int
seconds
=
(
int
)
time
->
sec
;
return
(
seconds
+
60
*
time
->
min
+
3600
*
time
->
hr
);
}
src/extend/datetime/datetime_functions.doc
已删除
100644 → 0
浏览文件 @
c6cf2182
From: Massimo Dal Zotto <dz@cs.unitn.it>
Date: Tue, 14 May 1996 14:31:18 +0200 (MET DST)
Subject: [PG95]: new postgres functions
- -----BEGIN PGP SIGNED MESSAGE-----
Some time ago I read in the mailing list requests of people looking
for more time and date functions. I have now written some of them:
time_difference(time1, time2) ,also defined as operator '-'
hour(time)
minutes(time)
seconds(time)
asMinutes(time)
asSeconds(time)
currentTime()
currentDate()
The file can be compiled as shared library and loaded as dynamic module
without need to recompile the backend. This can also be taken as an example
of the extensibility of postgres (user-defined functions, operators, etc).
I would be nice to see more of these user contributed modules posted to this
list and hopefully accessible from the Postgres home page.
src/extend/datetime/datetime_functions.sql
已删除
100644 → 0
浏览文件 @
c6cf2182
-- SQL code to load and define 'datetime' functions
-- load the new functions
load
'/home/dz/lib/postgres/datetime_functions.so'
;
-- define the new functions in postgres
create
function
time_difference
(
time
,
time
)
returns
time
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
currentDate
()
returns
date
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
currentTime
()
returns
time
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
hours
(
time
)
returns
int4
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
minutes
(
time
)
returns
int4
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
seconds
(
time
)
returns
int4
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
day
(
date
)
returns
int4
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
month
(
date
)
returns
int4
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
year
(
date
)
returns
int4
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
asMinutes
(
time
)
returns
int4
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
function
asSeconds
(
time
)
returns
int4
as
'/home/dz/lib/postgres/datetime_functions.so'
language
'c'
;
create
operator
-
(
leftarg
=
time
,
rightarg
=
time
,
procedure
=
time_difference
);
src/extend/soundex/soundex.c
已删除
100644 → 0
浏览文件 @
c6cf2182
/*****************************************************************************/
/* soundex.c */
/*****************************************************************************/
#include <string.h>
#include <stdio.h>
#include "postgres.h"
/* for char16, etc. */
#include "utils/palloc.h"
/* for palloc */
#include "libpq-fe.h"
/* for TUPLE */
#include <stdio.h>
#include <ctype.h>
/* prototype for soundex function */
char
*
soundex
(
char
*
instr
,
char
*
outstr
);
text
*
text_soundex
(
text
*
t
)
{
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
char
*
table
=
"01230120022455012623010202"
;
int
count
=
0
;
text
*
new_t
;
char
outstr
[
6
+
1
];
/* max length of soundex is 6 */
char
*
instr
;
/* make a null-terminated string */
instr
=
palloc
(
VARSIZE
(
t
)
+
1
);
memcpy
(
instr
,
VARDATA
(
t
),
VARSIZE
(
t
)
-
VARHDRSZ
);
instr
[
VARSIZE
(
t
)
-
VARHDRSZ
]
=
(
char
)
0
;
/* load soundex into outstr */
soundex
(
instr
,
outstr
);
/* Now the outstr contains the soundex of instr */
/* copy outstr to new_t */
new_t
=
(
text
*
)
palloc
(
strlen
(
outstr
)
+
VARHDRSZ
);
memset
(
new_t
,
0
,
strlen
(
outstr
)
+
1
);
VARSIZE
(
new_t
)
=
strlen
(
outstr
)
+
VARHDRSZ
;
memcpy
((
void
*
)
VARDATA
(
new_t
),
(
void
*
)
outstr
,
strlen
(
outstr
));
/* free instr */
pfree
(
instr
);
return
(
new_t
);
}
char
*
soundex
(
char
*
instr
,
char
*
outstr
)
{
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
char
*
table
=
"01230120022455012623010202"
;
int
count
=
0
;
while
(
!
isalpha
(
instr
[
0
])
&&
instr
[
0
])
++
instr
;
if
(
!
instr
[
0
])
{
/* Hey! Where'd the string go? */
outstr
[
0
]
=
(
char
)
0
;
return
outstr
;
}
if
(
toupper
(
instr
[
0
])
==
'P'
&&
toupper
(
instr
[
1
])
==
'H'
)
{
instr
[
0
]
=
'F'
;
instr
[
1
]
=
'A'
;
}
*
outstr
++
=
(
char
)
toupper
(
*
instr
++
);
while
(
*
instr
&&
count
<
5
)
{
if
(
isalpha
(
*
instr
)
&&
*
instr
!=
*
(
instr
-
1
))
{
*
outstr
=
table
[
toupper
(
instr
[
0
])
-
'A'
];
if
(
*
outstr
!=
'0'
)
{
++
outstr
;
++
count
;
}
}
++
instr
;
}
*
outstr
=
'\0'
;
return
(
outstr
);
}
src/extend/soundex/soundex.sql
已删除
100644 → 0
浏览文件 @
c6cf2182
--------------- soundex.sql:
CREATE
FUNCTION
text_soundex
(
text
)
RETURNS
text
AS
'/usr/local/postgres/postgres95/src/funcs/soundex.so'
LANGUAGE
'c'
;
SELECT
text_soundex
(
'hello world!'
);
CREATE
TABLE
s
(
nm
text
)
\
g
insert
into
s
values
(
'john'
)
\
g
insert
into
s
values
(
'joan'
)
\
g
insert
into
s
values
(
'wobbly'
)
\
g
select
*
from
s
where
text_soundex
(
nm
)
=
text_soundex
(
'john'
)
\
g
select
nm
from
s
a
,
s
b
where
text_soundex
(
a
.
nm
)
=
text_soundex
(
b
.
nm
)
and
a
.
oid
<>
b
.
oid
\
g
CREATE
FUNCTION
text_sx_eq
(
text
,
text
)
RETURNS
bool
AS
'select text_soundex($1) = text_soundex($2)'
LANGUAGE
'sql'
\
g
CREATE
FUNCTION
text_sx_lt
(
text
,
text
)
RETURNS
bool
AS
'select text_soundex($1) < text_soundex($2)'
LANGUAGE
'sql'
\
g
CREATE
FUNCTION
text_sx_gt
(
text
,
text
)
RETURNS
bool
AS
'select text_soundex($1) > text_soundex($2)'
LANGUAGE
'sql'
;
CREATE
FUNCTION
text_sx_le
(
text
,
text
)
RETURNS
bool
AS
'select text_soundex($1) <= text_soundex($2)'
LANGUAGE
'sql'
;
CREATE
FUNCTION
text_sx_ge
(
text
,
text
)
RETURNS
bool
AS
'select text_soundex($1) >= text_soundex($2)'
LANGUAGE
'sql'
;
CREATE
FUNCTION
text_sx_ne
(
text
,
text
)
RETURNS
bool
AS
'select text_soundex($1) <> text_soundex($2)'
LANGUAGE
'sql'
;
DROP
OPERATOR
#=
(
text
,
text
)
\
g
CREATE
OPERATOR
#=
(
leftarg
=
text
,
rightarg
=
text
,
procedure
=
text_sx_eq
,
commutator
=
text_sx_eq
)
\
g
SELECT
*
FROM
s
WHERE
text_sx_eq
(
nm
,
'john'
)
\
g
SELECT
*
from
s
where
s
.
nm
#=
'john'
;
src/extend/string/string_io.c
已删除
100644 → 0
浏览文件 @
c6cf2182
/*
* string_io.c --
*
* This file defines new input/output conversion routines for strings.
*
* Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it>
*/
#include <ctype.h>
#include <string.h>
#include "postgres.h"
#include "utils/elog.h"
#include "utils/palloc.h"
#include "utils/builtins.h"
/* define this if you want to see iso-8859 characters */
#define ISO8859
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define VALUE(char) ((char) - '0')
#define DIGIT(val) ((val) + '0')
#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
#ifndef ISO8859
#define NOTPRINTABLE(c) (!isprint(c))
#else
#define NOTPRINTABLE(c) (!isprint(c) && ((c) < 0xa0))
#endif
/*
* string_output() --
*
* This function takes a pointer to a string data and an optional
* data size and returns a printable representation of the data
* translating all escape sequences to C-like \nnn or \c escapes.
* The function is used by output methods of various string types.
*
* Arguments:
* data - input data (can be NULL)
* size - optional size of data. A negative value indicates
* that data is a null terminated string.
*
* Returns:
* a pointer to a new string containing the printable
* representation of data.
*/
char
*
string_output
(
char
*
data
,
int
size
)
{
register
unsigned
char
c
,
*
p
,
*
r
,
*
result
;
register
int
l
,
len
;
if
(
data
==
NULL
)
{
result
=
(
char
*
)
palloc
(
2
);
result
[
0
]
=
'-'
;
result
[
1
]
=
'\0'
;
return
(
result
);
}
if
(
size
<
0
)
{
size
=
strlen
(
data
);
}
/* adjust string length for escapes */
len
=
size
;
for
(
p
=
data
,
l
=
size
;
l
>
0
;
p
++
,
l
--
)
{
switch
(
*
p
)
{
case
'\\'
:
case
'"'
:
case
'{'
:
case
'}'
:
case
'\b'
:
case
'\f'
:
case
'\n'
:
case
'\r'
:
case
'\t'
:
case
'\v'
:
len
++
;
break
;
default:
if
(
NOTPRINTABLE
(
c
))
{
len
+=
3
;
}
}
}
len
++
;
result
=
(
char
*
)
palloc
(
len
);
for
(
p
=
data
,
r
=
result
,
l
=
size
;
(
l
>
0
)
&&
(
c
=
*
p
);
p
++
,
l
--
)
{
switch
(
c
)
{
case
'\\'
:
case
'"'
:
case
'{'
:
case
'}'
:
*
r
++
=
'\\'
;
*
r
++
=
c
;
break
;
case
'\b'
:
*
r
++
=
'\\'
;
*
r
++
=
'b'
;
break
;
case
'\f'
:
*
r
++
=
'\\'
;
*
r
++
=
'f'
;
break
;
case
'\n'
:
*
r
++
=
'\\'
;
*
r
++
=
'n'
;
break
;
case
'\r'
:
*
r
++
=
'\\'
;
*
r
++
=
'r'
;
break
;
case
'\t'
:
*
r
++
=
'\\'
;
*
r
++
=
't'
;
break
;
case
'\v'
:
*
r
++
=
'\\'
;
*
r
++
=
'v'
;
break
;
default:
if
(
NOTPRINTABLE
(
c
))
{
*
r
=
'\\'
;
r
+=
3
;
*
r
--
=
DIGIT
(
c
&
07
);
c
>>=
3
;
*
r
--
=
DIGIT
(
c
&
07
);
c
>>=
3
;
*
r
=
DIGIT
(
c
&
03
);
r
+=
3
;
}
else
{
*
r
++
=
c
;
}
}
}
*
r
=
'\0'
;
return
((
char
*
)
result
);
}
/*
* string_input() --
*
* This function accepts a C string in input and copies it into a new
* object allocated with palloc() translating all escape sequences.
* An optional header can be allocatd before the string, for example
* to hold the length of a varlena object.
* This function is not necessary for input from sql commands because
* the parser already does escape translation, all data input routines
* receive strings in internal form.
*
* Arguments:
* str - input string possibly with escapes
* size - the required size of new data. A value of 0
* indicates a variable size string, while a
* negative value indicates a variable size string
* of size not greater than this absolute value.
* hdrsize - size of an optional header to be allocated before
* the data. It must then be filled by the caller.
* rtn_size - an optional pointer to an int variable where the
* size of the new string is stored back.
*
* Returns:
* a pointer to the new string or the header.
*/
char
*
string_input
(
char
*
str
,
int
size
,
int
hdrsize
,
int
*
rtn_size
)
{
register
unsigned
char
*
p
,
*
r
;
unsigned
char
*
result
;
int
len
;
if
((
str
==
NULL
)
||
(
hdrsize
<
0
))
{
return
(
char
*
)
NULL
;
}
/* Compute result size */
len
=
strlen
(
str
);
for
(
p
=
str
;
*
p
;
)
{
if
(
*
p
++
==
'\\'
)
{
if
(
ISOCTAL
(
*
p
))
{
if
(
ISOCTAL
(
*
(
p
+
1
)))
{
p
++
;
len
--
;
}
if
(
ISOCTAL
(
*
(
p
+
1
)))
{
p
++
;
len
--
;
}
}
if
(
*
p
)
p
++
;
len
--
;
}
}
/* result has variable length */
if
(
size
==
0
)
{
size
=
len
+
1
;
}
else
/* result has variable length with maximum size */
if
(
size
<
0
)
{
size
=
MIN
(
len
,
-
size
)
+
1
;
}
result
=
(
char
*
)
palloc
(
hdrsize
+
size
);
memset
(
result
,
0
,
hdrsize
+
size
);
if
(
rtn_size
)
{
*
rtn_size
=
size
;
}
r
=
result
+
hdrsize
;
for
(
p
=
str
;
*
p
;
)
{
register
unsigned
char
c
;
if
((
c
=
*
p
++
)
==
'\\'
)
{
switch
(
c
=
*
p
++
)
{
case
'\0'
:
p
--
;
break
;
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
c
=
VALUE
(
c
);
if
(
isdigit
(
*
p
))
{
c
=
(
c
<<
3
)
+
VALUE
(
*
p
++
);
}
if
(
isdigit
(
*
p
))
{
c
=
(
c
<<
3
)
+
VALUE
(
*
p
++
);
}
*
r
++
=
c
;
break
;
case
'b'
:
*
r
++
=
'\b'
;
break
;
case
'f'
:
*
r
++
=
'\f'
;
break
;
case
'n'
:
*
r
++
=
'\n'
;
break
;
case
'r'
:
*
r
++
=
'\r'
;
break
;
case
't'
:
*
r
++
=
'\t'
;
break
;
case
'v'
:
*
r
++
=
'\v'
;
break
;
default:
*
r
++
=
c
;
}
}
else
{
*
r
++
=
c
;
}
}
return
((
char
*
)
result
);
}
char
*
c_charout
(
int32
c
)
{
char
str
[
2
];
str
[
0
]
=
(
char
)
c
;
str
[
1
]
=
'\0'
;
return
(
string_output
(
str
,
1
));
}
char
*
c_char2out
(
uint16
s
)
{
return
(
string_output
((
char
*
)
&
s
,
2
));
}
char
*
c_char4out
(
uint32
s
)
{
return
(
string_output
((
char
*
)
&
s
,
4
));
}
char
*
c_char8out
(
char
*
s
)
{
return
(
string_output
(
s
,
8
));
}
char
*
c_char16out
(
char
*
s
)
{
return
(
string_output
(
s
,
16
));
}
/*
* This can be used for text, bytea, SET and unknown data types
*/
char
*
c_textout
(
struct
varlena
*
vlena
)
{
int
len
=
0
;
char
*
s
=
NULL
;
if
(
vlena
)
{
len
=
VARSIZE
(
vlena
)
-
VARHDRSZ
;
s
=
VARDATA
(
vlena
);
}
return
(
string_output
(
s
,
len
));
}
/*
* This can be used for varchar and bpchar strings
*/
char
*
c_varcharout
(
char
*
s
)
{
int
len
;
if
(
s
)
{
len
=
*
(
int32
*
)
s
-
4
;
s
+=
4
;
}
return
(
string_output
(
s
,
len
));
}
#ifdef 0
struct
varlena
*
c_textin
(
char
*
str
)
{
struct
varlena
*
result
;
int
len
;
if
(
str
==
NULL
)
{
return
((
struct
varlena
*
)
NULL
);
}
result
=
(
struct
varlena
*
)
string_input
(
str
,
0
,
VARHDRSZ
,
&
len
);
VARSIZE
(
result
)
=
len
;
return
(
result
);
}
char
*
c_char16in
(
char
*
str
)
{
return
(
string_input
(
str
,
16
,
0
,
NULL
));
}
#endif
src/extend/string/string_io.sql
已删除
100644 → 0
浏览文件 @
c6cf2182
-
-
-- load the new functions
-
-
--
load
'/home/dz/lib/postgres/string_output.so'
;
-
-
-- create function c_textin(opaque)
-
-
-- returns text
-
-
-- as '/home/dz/lib/postgres/string_output.so'
-
-
-- language 'c';
create
function
c_charout
(
opaque
)
returns
int4
as
'/home/dz/lib/postgres/string_output.so'
language
'c'
;
create
function
c_char2out
(
opaque
)
returns
int4
as
'/home/dz/lib/postgres/string_output.so'
language
'c'
;
create
function
c_char4out
(
opaque
)
returns
int4
as
'/home/dz/lib/postgres/string_output.so'
language
'c'
;
create
function
c_char8out
(
opaque
)
returns
int4
as
'/home/dz/lib/postgres/string_output.so'
language
'c'
;
create
function
c_char16out
(
opaque
)
returns
int4
as
'/home/dz/lib/postgres/string_output.so'
language
'c'
;
create
function
c_textout
(
opaque
)
returns
int4
as
'/home/dz/lib/postgres/string_output.so'
language
'c'
;
create
function
c_varcharout
(
opaque
)
returns
int4
as
'/home/dz/lib/postgres/string_output.so'
language
'c'
;
-
-
-- define a function which sets the new output routines for char types
-
-
--
-
-
-- select c_mode();
-
-
--
create
function
c_mode
()
returns
text
as
'update pg_type set typoutput=
''
c_charout
''
where typname=
''
char
''\;
update pg_type set typoutput=
''
c_char2out
''
where typname=
''
char2
''\;
update pg_type set typoutput=
''
c_char4out
''
where typname=
''
char4
''\;
update pg_type set typoutput=
''
c_char8out
''
where typname=
''
char8
''\;
update pg_type set typoutput=
''
c_char16out
''
where typname=
''
char16
''\;
update pg_type set typoutput=
''
c_textout
''
where typname=
''
text
''\;
update pg_type set typoutput=
''
c_textout
''
where typname=
''
bytea
''\;
update pg_type set typoutput=
''
c_textout
''
where typname=
''
unknown
''\;
update pg_type set typoutput=
''
c_textout
''
where typname=
''
SET
''\;
update pg_type set typoutput=
''
c_varcharout
''
where typname=
''
varchar
''\;
update pg_type set typoutput=
''
c_varcharout
''
where typname=
''
bpchar
''\;
select
''
c_mode
''
::text'
language
'sql'
;
-
-
-- define a function which restores the original routines for char types
-
-
--
-
-
-- select pg_mode();
-
-
--
create
function
pg_mode
()
returns
text
as
'update pg_type set typoutput=
''
charout
''
where typname=
''
char
''\;
update pg_type set typoutput=
''
char2out
''
where typname=
''
char2
''\;
update pg_type set typoutput=
''
char4out
''
where typname=
''
char4
''\;
update pg_type set typoutput=
''
char8out
''
where typname=
''
char8
''\;
update pg_type set typoutput=
''
char16out
''
where typname=
''
char16
''\;
update pg_type set typoutput=
''
textout
''
where typname=
''
text
''\;
update pg_type set typoutput=
''
textout
''
where typname=
''
bytea
''\;
update pg_type set typoutput=
''
textout
''
where typname=
''
unknown
''\;
update pg_type set typoutput=
''
textout
''
where typname=
''
SET
''\;
update pg_type set typoutput=
''
varcharout
''
where typname=
''
varchar
''\;
update pg_type set typoutput=
''
varcharout
''
where typname=
''
bpchar
''\;
select
''
pg_mode
''
::text'
language
'sql'
;
-
-
-- or do the changes manually
-
-
--
-
-
-- update pg_type set typoutput='charout' where typname='char';
-
-
-- update pg_type set typoutput='char2out' where typname='char2';
-
-
-- update pg_type set typoutput='char4out' where typname='char4';
-
-
-- update pg_type set typoutput='char8out' where typname='char8';
-
-
-- update pg_type set typoutput='char16out' where typname='char16';
-
-
-- update pg_type set typoutput='textout' where typname='text';
-
-
-- update pg_type set typoutput='textout' where typname='bytea';
-
-
-- update pg_type set typoutput='textout' where typname='unknown';
-
-
-- update pg_type set typoutput='textout' where typname='SET';
-
-
-- update pg_type set typoutput='varcharout' where typname='varchar';
-
-
-- update pg_type set typoutput='varcharout' where typname='bpchar';
-
-
--
-
-
-- update pg_type set typoutput='c_charout' where typname='char';
-
-
-- update pg_type set typoutput='c_char2out' where typname='char2';
-
-
-- update pg_type set typoutput='c_char4out' where typname='char4';
-
-
-- update pg_type set typoutput='c_char8out' where typname='char8';
-
-
-- update pg_type set typoutput='c_char16out' where typname='char16';
-
-
-- update pg_type set typoutput='c_textout' where typname='text';
-
-
-- update pg_type set typoutput='c_textout' where typname='bytea';
-
-
-- update pg_type set typoutput='c_textout' where typname='unknown';
-
-
-- update pg_type set typoutput='c_textout' where typname='SET';
-
-
-- update pg_type set typoutput='c_varcharout' where typname='varchar';
-
-
-- update pg_type set typoutput='c_varcharout' where typname='bpchar';
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录