From 5eb17f53b61e033ed65a428cff50c4d3e58c7178 Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" Date: Wed, 31 Jul 1996 02:30:10 +0000 Subject: [PATCH] Moved src/extend to contrib --- src/extend/array/array_iterator.c | 251 -------------- src/extend/array/array_iterator.doc | 26 -- src/extend/array/array_iterator.sql | 137 -------- src/extend/datetime/datetime_functions.c | 147 --------- src/extend/datetime/datetime_functions.doc | 25 -- src/extend/datetime/datetime_functions.sql | 69 ---- src/extend/soundex/soundex.c | 83 ----- src/extend/soundex/soundex.sql | 57 ---- src/extend/string/string_io.c | 361 --------------------- src/extend/string/string_io.sql | 111 ------- 10 files changed, 1267 deletions(-) delete mode 100644 src/extend/array/array_iterator.c delete mode 100644 src/extend/array/array_iterator.doc delete mode 100644 src/extend/array/array_iterator.sql delete mode 100644 src/extend/datetime/datetime_functions.c delete mode 100644 src/extend/datetime/datetime_functions.doc delete mode 100644 src/extend/datetime/datetime_functions.sql delete mode 100644 src/extend/soundex/soundex.c delete mode 100644 src/extend/soundex/soundex.sql delete mode 100644 src/extend/string/string_io.c delete mode 100644 src/extend/string/string_io.sql diff --git a/src/extend/array/array_iterator.c b/src/extend/array/array_iterator.c deleted file mode 100644 index 95ab119f85..0000000000 --- a/src/extend/array/array_iterator.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * 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_" 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 - */ - -#include -#include -#include -#include - -#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); -} diff --git a/src/extend/array/array_iterator.doc b/src/extend/array/array_iterator.doc deleted file mode 100644 index 01c1b2195c..0000000000 --- a/src/extend/array/array_iterator.doc +++ /dev/null @@ -1,26 +0,0 @@ -From: Massimo Dal Zotto -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. - diff --git a/src/extend/array/array_iterator.sql b/src/extend/array/array_iterator.sql deleted file mode 100644 index 7a3356266c..0000000000 --- a/src/extend/array/array_iterator.sql +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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 */ - diff --git a/src/extend/datetime/datetime_functions.c b/src/extend/datetime/datetime_functions.c deleted file mode 100644 index dc1fec8bd2..0000000000 --- a/src/extend/datetime/datetime_functions.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * datetime_functions.c -- - * - * This file defines new functions for the time and date data types. - * - * Copyright (c) 1996, Massimo Dal Zotto - */ - -#include - -#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(¤t_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(¤t_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); -} - diff --git a/src/extend/datetime/datetime_functions.doc b/src/extend/datetime/datetime_functions.doc deleted file mode 100644 index 0c7a01819a..0000000000 --- a/src/extend/datetime/datetime_functions.doc +++ /dev/null @@ -1,25 +0,0 @@ -From: Massimo Dal Zotto -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. - - diff --git a/src/extend/datetime/datetime_functions.sql b/src/extend/datetime/datetime_functions.sql deleted file mode 100644 index 2e50a4a19f..0000000000 --- a/src/extend/datetime/datetime_functions.sql +++ /dev/null @@ -1,69 +0,0 @@ - --- 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); - diff --git a/src/extend/soundex/soundex.c b/src/extend/soundex/soundex.c deleted file mode 100644 index 2ce6ef510f..0000000000 --- a/src/extend/soundex/soundex.c +++ /dev/null @@ -1,83 +0,0 @@ -/*****************************************************************************/ -/* soundex.c */ -/*****************************************************************************/ - -#include -#include -#include "postgres.h" /* for char16, etc. */ -#include "utils/palloc.h" /* for palloc */ -#include "libpq-fe.h" /* for TUPLE */ -#include -#include - -/* 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); -} - diff --git a/src/extend/soundex/soundex.sql b/src/extend/soundex/soundex.sql deleted file mode 100644 index af8ea41fd2..0000000000 --- a/src/extend/soundex/soundex.sql +++ /dev/null @@ -1,57 +0,0 @@ ---------------- 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'; - diff --git a/src/extend/string/string_io.c b/src/extend/string/string_io.c deleted file mode 100644 index ab49c5321a..0000000000 --- a/src/extend/string/string_io.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * string_io.c -- - * - * This file defines new input/output conversion routines for strings. - * - * Copyright (c) 1996, Massimo Dal Zotto - */ - -#include -#include - -#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 - diff --git a/src/extend/string/string_io.sql b/src/extend/string/string_io.sql deleted file mode 100644 index 011371707d..0000000000 --- a/src/extend/string/string_io.sql +++ /dev/null @@ -1,111 +0,0 @@ - -- - -- 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'; - -- 2.40.0