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
5eb17f53
Commit
5eb17f53
authored
Jul 31, 1996
by
Marc G. Fournier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved src/extend to contrib
parent
c6cf2182
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
0 additions
and
1267 deletions
+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
No files found.
src/extend/array/array_iterator.c
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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
deleted
100644 → 0
View file @
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';
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