📄 varlena.c
字号:
text *arg2 = PG_GETARG_TEXT_P(1); int32 result; result = text_cmp(arg1, arg2); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_INT32(result);}Datumtext_larger(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); text *result; result = ((text_cmp(arg1, arg2) > 0) ? arg1 : arg2); PG_RETURN_TEXT_P(result);}Datumtext_smaller(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); text *result; result = ((text_cmp(arg1, arg2) < 0) ? arg1 : arg2); PG_RETURN_TEXT_P(result);}/* * The following operators support character-by-character comparison * of text data types, to allow building indexes suitable for LIKE * clauses. */static intinternal_text_pattern_compare(text *arg1, text *arg2){ int result; result = memcmp(VARDATA(arg1), VARDATA(arg2), Min(VARSIZE(arg1), VARSIZE(arg2)) - VARHDRSZ); if (result != 0) return result; else if (VARSIZE(arg1) < VARSIZE(arg2)) return -1; else if (VARSIZE(arg1) > VARSIZE(arg2)) return 1; else return 0;}Datumtext_pattern_lt(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); int result; result = internal_text_pattern_compare(arg1, arg2); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL(result < 0);}Datumtext_pattern_le(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); int result; result = internal_text_pattern_compare(arg1, arg2); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL(result <= 0);}Datumtext_pattern_eq(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); int result; if (VARSIZE(arg1) != VARSIZE(arg2)) result = 1; else result = internal_text_pattern_compare(arg1, arg2); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL(result == 0);}Datumtext_pattern_ge(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); int result; result = internal_text_pattern_compare(arg1, arg2); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL(result >= 0);}Datumtext_pattern_gt(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); int result; result = internal_text_pattern_compare(arg1, arg2); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL(result > 0);}Datumtext_pattern_ne(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); int result; if (VARSIZE(arg1) != VARSIZE(arg2)) result = 1; else result = internal_text_pattern_compare(arg1, arg2); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL(result != 0);}Datumbttext_pattern_cmp(PG_FUNCTION_ARGS){ text *arg1 = PG_GETARG_TEXT_P(0); text *arg2 = PG_GETARG_TEXT_P(1); int result; result = internal_text_pattern_compare(arg1, arg2); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_INT32(result);}/*------------------------------------------------------------- * byteaoctetlen * * get the number of bytes contained in an instance of type 'bytea' *------------------------------------------------------------- */Datumbyteaoctetlen(PG_FUNCTION_ARGS){ Datum str = PG_GETARG_DATUM(0); /* We need not detoast the input at all */ PG_RETURN_INT32(toast_raw_datum_size(str) - VARHDRSZ);}/* * byteacat - * takes two bytea* and returns a bytea* that is the concatenation of * the two. * * Cloned from textcat and modified as required. */Datumbyteacat(PG_FUNCTION_ARGS){ bytea *t1 = PG_GETARG_BYTEA_P(0); bytea *t2 = PG_GETARG_BYTEA_P(1); int len1, len2, len; bytea *result; char *ptr; len1 = VARSIZE(t1) - VARHDRSZ; if (len1 < 0) len1 = 0; len2 = VARSIZE(t2) - VARHDRSZ; if (len2 < 0) len2 = 0; len = len1 + len2 + VARHDRSZ; result = (bytea *) palloc(len); /* Set size of result string... */ VARATT_SIZEP(result) = len; /* Fill data field of result string... */ ptr = VARDATA(result); if (len1 > 0) memcpy(ptr, VARDATA(t1), len1); if (len2 > 0) memcpy(ptr + len1, VARDATA(t2), len2); PG_RETURN_BYTEA_P(result);}#define PG_STR_GET_BYTEA(str_) \ DatumGetByteaP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))/* * bytea_substr() * Return a substring starting at the specified position. * Cloned from text_substr and modified as required. * * Input: * - string * - starting position (is one-based) * - string length (optional) * * If the starting position is zero or less, then return from the start of the string * adjusting the length to be consistent with the "negative start" per SQL92. * If the length is less than zero, an ERROR is thrown. If no third argument * (length) is provided, the length to the end of the string is assumed. */Datumbytea_substr(PG_FUNCTION_ARGS){ int S = PG_GETARG_INT32(1); /* start position */ int S1; /* adjusted start position */ int L1; /* adjusted substring length */ S1 = Max(S, 1); if (fcinfo->nargs == 2) { /* * Not passed a length - PG_GETARG_BYTEA_P_SLICE() grabs everything to * the end of the string if we pass it a negative value for length. */ L1 = -1; } else { /* end position */ int E = S + PG_GETARG_INT32(2); /* * A negative value for L is the only way for the end position to be * before the start. SQL99 says to throw an error. */ if (E < S) ereport(ERROR, (errcode(ERRCODE_SUBSTRING_ERROR), errmsg("negative substring length not allowed"))); /* * A zero or negative value for the end position can happen if the * start was negative or one. SQL99 says to return a zero-length * string. */ if (E < 1) PG_RETURN_BYTEA_P(PG_STR_GET_BYTEA("")); L1 = E - S1; } /* * If the start position is past the end of the string, SQL99 says to * return a zero-length string -- PG_GETARG_TEXT_P_SLICE() will do that * for us. Convert to zero-based starting position */ PG_RETURN_BYTEA_P(PG_GETARG_BYTEA_P_SLICE(0, S1 - 1, L1));}/* * bytea_substr_no_len - * Wrapper to avoid opr_sanity failure due to * one function accepting a different number of args. */Datumbytea_substr_no_len(PG_FUNCTION_ARGS){ return bytea_substr(fcinfo);}/* * byteapos - * Return the position of the specified substring. * Implements the SQL92 POSITION() function. * Cloned from textpos and modified as required. */Datumbyteapos(PG_FUNCTION_ARGS){ bytea *t1 = PG_GETARG_BYTEA_P(0); bytea *t2 = PG_GETARG_BYTEA_P(1); int pos; int px, p; int len1, len2; char *p1, *p2; if (VARSIZE(t2) <= VARHDRSZ) PG_RETURN_INT32(1); /* result for empty pattern */ 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) && (memcmp(p1, p2, len2) == 0)) { pos = p + 1; break; }; p1++; }; PG_RETURN_INT32(pos);}/*------------------------------------------------------------- * byteaGetByte * * this routine treats "bytea" as an array of bytes. * It returns the Nth byte (a number between 0 and 255). *------------------------------------------------------------- */DatumbyteaGetByte(PG_FUNCTION_ARGS){ bytea *v = PG_GETARG_BYTEA_P(0); int32 n = PG_GETARG_INT32(1); int len; int byte; len = VARSIZE(v) - VARHDRSZ; if (n < 0 || n >= len) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("index %d out of valid range, 0..%d", n, len - 1))); byte = ((unsigned char *) VARDATA(v))[n]; PG_RETURN_INT32(byte);}/*------------------------------------------------------------- * byteaGetBit * * This routine treats a "bytea" type like an array of bits. * It returns the value of the Nth bit (0 or 1). * *------------------------------------------------------------- */DatumbyteaGetBit(PG_FUNCTION_ARGS){ bytea *v = PG_GETARG_BYTEA_P(0); int32 n = PG_GETARG_INT32(1); int byteNo, bitNo; int len; int byte; len = VARSIZE(v) - VARHDRSZ; if (n < 0 || n >= len * 8) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("index %d out of valid range, 0..%d", n, len * 8 - 1))); byteNo = n / 8; bitNo = n % 8; byte = ((unsigned char *) VARDATA(v))[byteNo]; if (byte & (1 << bitNo)) PG_RETURN_INT32(1); else PG_RETURN_INT32(0);}/*------------------------------------------------------------- * byteaSetByte * * Given an instance of type 'bytea' creates a new one with * the Nth byte set to the given value. * *------------------------------------------------------------- */DatumbyteaSetByte(PG_FUNCTION_ARGS){ bytea *v = PG_GETARG_BYTEA_P(0); int32 n = PG_GETARG_INT32(1); int32 newByte = PG_GETARG_INT32(2); int len; bytea *res; len = VARSIZE(v) - VARHDRSZ; if (n < 0 || n >= len) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("index %d out of valid range, 0..%d", n, len - 1))); /* * Make a copy of the original varlena. */ res = (bytea *) palloc(VARSIZE(v)); memcpy((char *) res, (char *) v, VARSIZE(v)); /* * Now set the byte. */ ((unsigned char *) VARDATA(res))[n] = newByte; PG_RETURN_BYTEA_P(res);}/*------------------------------------------------------------- * byteaSetBit * * Given an instance of type 'bytea' creates a new one with * the Nth bit set to the given value. * *------------------------------------------------------------- */DatumbyteaSetBit(PG_FUNCTION_ARGS){ bytea *v = PG_GETARG_BYTEA_P(0); int32 n = PG_GETARG_INT32(1); int32 newBit = PG_GETARG_INT32(2); bytea *res; int len; int oldByte, newByte; int byteNo, bitNo; len = VARSIZE(v) - VARHDRSZ; if (n < 0 || n >= len * 8) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("index %d out of valid range, 0..%d", n, len * 8 - 1))); byteNo = n / 8; bitNo = n % 8; /* * sanity check! */ if (newBit != 0 && newBit != 1) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("new bit must be 0 or 1"))); /* * Make a copy of the original varlena. */ res = (bytea *) palloc(VARSIZE(v)); memcpy((char *) res, (char *) v, VARSIZE(v)); /* * Update the byte. */ oldByte = ((unsigned char *) VARDATA(res))[byteNo]; if (newBit == 0) newByte = oldByte & (~(1 << bitNo)); else newByte = oldByte | (1 << bitNo); ((unsigned char *) VARDATA(res))[byteNo] = newByte; PG_RETURN_BYTEA_P(res);}/* text_name() * Converts a text type to a Name type. */Datumtext_name(PG_FUNCTION_ARGS){ text *s = PG_GETARG_TEXT_P(0); Name result; int len; len = VARSIZE(s) - VARHDRSZ; /* Truncate oversize input */ if (len >= NAMEDATALEN) len = NAMEDATALEN - 1;#ifdef STRINGDEBUG printf("text- convert string length %d (%d) ->%d\n", VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);#endif result = (Name) palloc(NAMEDATALEN); memcpy(NameStr(*result), VARDATA(s), len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -