mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Add routines for text trimming on both ends, substring, and string position.
Used to support SQL92 compatibility.
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Edmund Mergl <E.Mergl@bawue.de>
|
* Edmund Mergl <E.Mergl@bawue.de>
|
||||||
*
|
*
|
||||||
* $Id: oracle_compat.c,v 1.6 1997/05/07 02:46:45 scrappy Exp $
|
* $Id: oracle_compat.c,v 1.7 1997/07/29 16:12:01 thomas Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ text *upper(text *string);
|
|||||||
text *initcap(text *string);
|
text *initcap(text *string);
|
||||||
text *lpad(text *string1, int4 len, text *string2);
|
text *lpad(text *string1, int4 len, text *string2);
|
||||||
text *rpad(text *string1, int4 len, text *string2);
|
text *rpad(text *string1, int4 len, text *string2);
|
||||||
|
text *btrim(text *string, text *set);
|
||||||
text *ltrim(text *string, text *set);
|
text *ltrim(text *string, text *set);
|
||||||
text *rtrim(text *string, text *set);
|
text *rtrim(text *string, text *set);
|
||||||
text *substr(text *string, int4 m, int4 n);
|
text *substr(text *string, int4 m, int4 n);
|
||||||
@ -246,6 +247,81 @@ rpad(text *string1, int4 len, text *string2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
*
|
||||||
|
* btrim
|
||||||
|
*
|
||||||
|
* Syntax:
|
||||||
|
*
|
||||||
|
* text *btrim(text *string, text *set)
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Returns string with characters removed from the front and back
|
||||||
|
* up to the first character not in set.
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
text *
|
||||||
|
btrim(text *string, text *set)
|
||||||
|
{
|
||||||
|
text *ret;
|
||||||
|
char *ptr, *end, *ptr2, *end2;
|
||||||
|
int m;
|
||||||
|
|
||||||
|
if ((string == (text *)NULL) ||
|
||||||
|
((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
|
||||||
|
(set == (text *)NULL) ||
|
||||||
|
((VARSIZE(set) - VARHDRSZ) <= 0))
|
||||||
|
return string;
|
||||||
|
|
||||||
|
ptr = VARDATA(string);
|
||||||
|
ptr2 = VARDATA(set);
|
||||||
|
end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
|
||||||
|
|
||||||
|
while (m--) {
|
||||||
|
while (ptr2 <= end2) {
|
||||||
|
if (*ptr == *ptr2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++ptr2;
|
||||||
|
}
|
||||||
|
if (*ptr != *ptr2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
ptr2 = VARDATA(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
++m;
|
||||||
|
|
||||||
|
end = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
|
||||||
|
ptr2 = VARDATA(set);
|
||||||
|
|
||||||
|
while (m--) {
|
||||||
|
while (ptr2 <= end2) {
|
||||||
|
if (*end == *ptr2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++ptr2;
|
||||||
|
}
|
||||||
|
if (*end != *ptr2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--end;
|
||||||
|
ptr2 = VARDATA(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
++m;
|
||||||
|
|
||||||
|
ret = (text *)palloc(VARHDRSZ + m);
|
||||||
|
VARSIZE(ret) = VARHDRSZ + m;
|
||||||
|
memcpy(VARDATA(ret),ptr,m);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} /* btrim() */
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
*
|
*
|
||||||
* ltrim
|
* ltrim
|
||||||
@ -265,7 +341,7 @@ text *
|
|||||||
ltrim(text *string, text *set)
|
ltrim(text *string, text *set)
|
||||||
{
|
{
|
||||||
text *ret;
|
text *ret;
|
||||||
char *ptr, *ptr2, *end2, *ptr_ret;
|
char *ptr, *ptr2, *end2;
|
||||||
int m;
|
int m;
|
||||||
|
|
||||||
if ((string == (text *)NULL) ||
|
if ((string == (text *)NULL) ||
|
||||||
@ -297,11 +373,7 @@ ltrim(text *string, text *set)
|
|||||||
ret = (text *)palloc(VARHDRSZ + m);
|
ret = (text *)palloc(VARHDRSZ + m);
|
||||||
VARSIZE(ret) = VARHDRSZ + m;
|
VARSIZE(ret) = VARHDRSZ + m;
|
||||||
|
|
||||||
ptr_ret = VARDATA(ret);
|
memcpy(VARDATA(ret),ptr,m);
|
||||||
|
|
||||||
while (m--) {
|
|
||||||
*ptr_ret++ = *ptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -357,6 +429,9 @@ rtrim(text *string, text *set)
|
|||||||
|
|
||||||
ret = (text *)palloc(VARHDRSZ + m);
|
ret = (text *)palloc(VARHDRSZ + m);
|
||||||
VARSIZE(ret) = VARHDRSZ + m;
|
VARSIZE(ret) = VARHDRSZ + m;
|
||||||
|
#if FALSE
|
||||||
|
memcpy(VARDATA(ret),ptr-VARSIZE(ret)+m,m);
|
||||||
|
#endif
|
||||||
|
|
||||||
ptr_ret = VARDATA(ret) + m - 1;
|
ptr_ret = VARDATA(ret) + m - 1;
|
||||||
|
|
||||||
@ -454,11 +529,3 @@ translate(text *string, char from, char to)
|
|||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.16 1997/06/11 05:18:02 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.17 1997/07/29 16:12:07 thomas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -216,40 +216,81 @@ int textlen (text* t)
|
|||||||
/*
|
/*
|
||||||
* textcat -
|
* textcat -
|
||||||
* takes two text* and returns a text* that is the concatentation of
|
* takes two text* and returns a text* that is the concatentation of
|
||||||
* the two
|
* the two.
|
||||||
*/
|
*
|
||||||
|
* Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
|
||||||
/*
|
* Updated by Thomas, Thomas.Lockhart@jpl.nasa.gov 1997-07-10.
|
||||||
* Rewrited by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
|
* Allocate space for output in all cases.
|
||||||
|
* XXX - thomas 1997-07-10
|
||||||
|
* As in previous code, allow concatenation when one string is NULL.
|
||||||
|
* Is this OK?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
text*
|
text*
|
||||||
textcat(text* t1, text* t2)
|
textcat(text* t1, text* t2)
|
||||||
{
|
{
|
||||||
int len1, len2, newlen;
|
int len1, len2, len;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
text* result;
|
text* result;
|
||||||
|
|
||||||
/* Check for NULL strings... */
|
if (!PointerIsValid(t1) && !PointerIsValid(t2))
|
||||||
if (t1 == NULL) return t2;
|
return(NULL);
|
||||||
if (t2 == NULL) return t1;
|
|
||||||
|
|
||||||
/* Check for ZERO-LENGTH strings... */
|
len1 = (PointerIsValid(t1)? (VARSIZE(t1) - VARHDRSZ): 0);
|
||||||
/* I use <= instead of == , I know - it's paranoia, but... */
|
if (len1 < 0) len1 = 0;
|
||||||
if((len1 = VARSIZE(t1) - VARHDRSZ) <= 0) return t2;
|
len2 = (PointerIsValid(t2)? (VARSIZE(t2) - VARHDRSZ): 0);
|
||||||
if((len2 = VARSIZE(t2) - VARHDRSZ) <= 0) return t1;
|
if (len2 < 0) len2 = 0;
|
||||||
|
|
||||||
result = (text *)palloc(newlen = len1 + len2 + VARHDRSZ);
|
result = PALLOC(len = len1 + len2 + VARHDRSZ);
|
||||||
|
|
||||||
/* Fill data field of result string... */
|
/* Fill data field of result string... */
|
||||||
memcpy(ptr = VARDATA(result), VARDATA(t1), len1);
|
ptr = VARDATA(result);
|
||||||
memcpy(ptr + len1, VARDATA(t2), len2);
|
if (PointerIsValid(t1)) memcpy(ptr, VARDATA(t1), len1);
|
||||||
|
if (PointerIsValid(t2)) memcpy(ptr + len1, VARDATA(t2), len2);
|
||||||
|
|
||||||
/* Set size of result string... */
|
/* Set size of result string... */
|
||||||
VARSIZE(result) = newlen;
|
VARSIZE(result) = len;
|
||||||
|
|
||||||
return result;
|
return(result);
|
||||||
}
|
} /* textcat() */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* textpos -
|
||||||
|
* Return the position of the specified substring.
|
||||||
|
* Implements the SQL92 POSITION() function.
|
||||||
|
* Ref: A Guide To The SQL Standard, Date & Darwen, 1997
|
||||||
|
* - thomas 1997-07-27
|
||||||
|
*/
|
||||||
|
|
||||||
|
int32
|
||||||
|
textpos(text* t1, text* t2)
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
int px, p;
|
||||||
|
int len1, len2;
|
||||||
|
char *p1, *p2;
|
||||||
|
|
||||||
|
if (!PointerIsValid(t1) || !PointerIsValid(t2))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (VARSIZE(t2) <= 0)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
len1 = (VARSIZE(t1) - VARHDRSZ);
|
||||||
|
len2 = (VARSIZE(t2) - VARHDRSZ);
|
||||||
|
p1 = VARDATA(t1);
|
||||||
|
p2 = VARDATA(t2);
|
||||||
|
pos = 0;
|
||||||
|
px = (len1 - len2);
|
||||||
|
for (p = 0; p <= px; p++) {
|
||||||
|
if ((*p2 == *p1) && (strncmp(p1, p2, len2) == 0)) {
|
||||||
|
pos = p + 1;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
p1++;
|
||||||
|
};
|
||||||
|
return(pos);
|
||||||
|
} /* textpos() */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* texteq - returns 1 iff arguments are equal
|
* texteq - returns 1 iff arguments are equal
|
||||||
@ -269,15 +310,15 @@ texteq(struct varlena *arg1, struct varlena *arg2)
|
|||||||
a2p = arg2->vl_dat;
|
a2p = arg2->vl_dat;
|
||||||
/*
|
/*
|
||||||
* Varlenas are stored as the total size (data + size variable)
|
* Varlenas are stored as the total size (data + size variable)
|
||||||
* followed by the data. The size variable is an int32 so the
|
* followed by the data.
|
||||||
* length of the data is the total length less sizeof(int32)
|
* Use VARHDRSZ instead of explicit sizeof() - thomas 1997-07-10
|
||||||
*/
|
*/
|
||||||
len -= sizeof(int32);
|
len -= VARHDRSZ;
|
||||||
while (len-- != 0)
|
while (len-- != 0)
|
||||||
if (*a1p++ != *a2p++)
|
if (*a1p++ != *a2p++)
|
||||||
return((bool) 0);
|
return((bool) 0);
|
||||||
return((bool) 1);
|
return((bool) 1);
|
||||||
}
|
} /* texteq() */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
textne(struct varlena *arg1, struct varlena *arg2)
|
textne(struct varlena *arg1, struct varlena *arg2)
|
||||||
|
Reference in New Issue
Block a user