varlena.c
来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 2,310 行 · 第 1/4 页
C
2,310 行
if (*nextp == separator) { nextp++; while (isspace((unsigned char) *nextp)) nextp++; /* skip leading whitespace for next */ /* we expect another name, so done remains false */ } else if (*nextp == '\0') done = true; else return false; /* invalid syntax */ /* Now safe to overwrite separator with a null */ *endp = '\0'; /* Truncate name if it's overlength */ truncate_identifier(curname, strlen(curname), false); /* * Finished isolating current name --- add it to list */ *namelist = lappend(*namelist, curname); /* Loop back if we didn't reach end of string */ } while (!done); return true;}/***************************************************************************** * Comparison Functions used for bytea * * Note: btree indexes need these routines not to leak memory; therefore, * be careful to free working copies of toasted datums. Most places don't * need to be so careful. *****************************************************************************/Datumbyteaeq(PG_FUNCTION_ARGS){ bytea *arg1 = PG_GETARG_BYTEA_P(0); bytea *arg2 = PG_GETARG_BYTEA_P(1); int len1, len2; bool result; len1 = VARSIZE(arg1) - VARHDRSZ; len2 = VARSIZE(arg2) - VARHDRSZ; /* fast path for different-length inputs */ if (len1 != len2) result = false; else result = (memcmp(VARDATA(arg1), VARDATA(arg2), len1) == 0); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL(result);}Datumbyteane(PG_FUNCTION_ARGS){ bytea *arg1 = PG_GETARG_BYTEA_P(0); bytea *arg2 = PG_GETARG_BYTEA_P(1); int len1, len2; bool result; len1 = VARSIZE(arg1) - VARHDRSZ; len2 = VARSIZE(arg2) - VARHDRSZ; /* fast path for different-length inputs */ if (len1 != len2) result = true; else result = (memcmp(VARDATA(arg1), VARDATA(arg2), len1) != 0); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL(result);}Datumbytealt(PG_FUNCTION_ARGS){ bytea *arg1 = PG_GETARG_BYTEA_P(0); bytea *arg2 = PG_GETARG_BYTEA_P(1); int len1, len2; int cmp; len1 = VARSIZE(arg1) - VARHDRSZ; len2 = VARSIZE(arg2) - VARHDRSZ; cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2)); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));}Datumbyteale(PG_FUNCTION_ARGS){ bytea *arg1 = PG_GETARG_BYTEA_P(0); bytea *arg2 = PG_GETARG_BYTEA_P(1); int len1, len2; int cmp; len1 = VARSIZE(arg1) - VARHDRSZ; len2 = VARSIZE(arg2) - VARHDRSZ; cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2)); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));}Datumbyteagt(PG_FUNCTION_ARGS){ bytea *arg1 = PG_GETARG_BYTEA_P(0); bytea *arg2 = PG_GETARG_BYTEA_P(1); int len1, len2; int cmp; len1 = VARSIZE(arg1) - VARHDRSZ; len2 = VARSIZE(arg2) - VARHDRSZ; cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2)); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));}Datumbyteage(PG_FUNCTION_ARGS){ bytea *arg1 = PG_GETARG_BYTEA_P(0); bytea *arg2 = PG_GETARG_BYTEA_P(1); int len1, len2; int cmp; len1 = VARSIZE(arg1) - VARHDRSZ; len2 = VARSIZE(arg2) - VARHDRSZ; cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2)); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));}Datumbyteacmp(PG_FUNCTION_ARGS){ bytea *arg1 = PG_GETARG_BYTEA_P(0); bytea *arg2 = PG_GETARG_BYTEA_P(1); int len1, len2; int cmp; len1 = VARSIZE(arg1) - VARHDRSZ; len2 = VARSIZE(arg2) - VARHDRSZ; cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2)); if ((cmp == 0) && (len1 != len2)) cmp = (len1 < len2) ? -1 : 1; PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); PG_RETURN_INT32(cmp);}/* * replace_text * replace all occurrences of 'old_sub_str' in 'orig_str' * with 'new_sub_str' to form 'new_str' * * returns 'orig_str' if 'old_sub_str' == '' or 'orig_str' == '' * otherwise returns 'new_str' */Datumreplace_text(PG_FUNCTION_ARGS){ text *left_text; text *right_text; text *buf_text; text *ret_text; int curr_posn; text *src_text = PG_GETARG_TEXT_P(0); int src_text_len = TEXTLEN(src_text); text *from_sub_text = PG_GETARG_TEXT_P(1); int from_sub_text_len = TEXTLEN(from_sub_text); text *to_sub_text = PG_GETARG_TEXT_P(2); char *to_sub_str = PG_TEXT_GET_STR(to_sub_text); StringInfo str = makeStringInfo(); if (src_text_len == 0 || from_sub_text_len == 0) PG_RETURN_TEXT_P(src_text); buf_text = TEXTDUP(src_text); curr_posn = TEXTPOS(buf_text, from_sub_text); while (curr_posn > 0) { left_text = LEFT(buf_text, from_sub_text); right_text = RIGHT(buf_text, from_sub_text, from_sub_text_len); appendStringInfoString(str, PG_TEXT_GET_STR(left_text)); appendStringInfoString(str, to_sub_str); pfree(buf_text); pfree(left_text); buf_text = right_text; curr_posn = TEXTPOS(buf_text, from_sub_text); } appendStringInfoString(str, PG_TEXT_GET_STR(buf_text)); pfree(buf_text); ret_text = PG_STR_GET_TEXT(str->data); pfree(str->data); pfree(str); PG_RETURN_TEXT_P(ret_text);}/* * split_text * parse input string * return ord item (1 based) * based on provided field separator */Datumsplit_text(PG_FUNCTION_ARGS){ text *inputstring = PG_GETARG_TEXT_P(0); int inputstring_len = TEXTLEN(inputstring); text *fldsep = PG_GETARG_TEXT_P(1); int fldsep_len = TEXTLEN(fldsep); int fldnum = PG_GETARG_INT32(2); int start_posn = 0; int end_posn = 0; text *result_text; /* return empty string for empty input string */ if (inputstring_len < 1) PG_RETURN_TEXT_P(PG_STR_GET_TEXT("")); /* empty field separator */ if (fldsep_len < 1) { if (fldnum == 1) /* first field - just return the input * string */ PG_RETURN_TEXT_P(inputstring); else/* otherwise return an empty string */ PG_RETURN_TEXT_P(PG_STR_GET_TEXT("")); } /* field number is 1 based */ if (fldnum < 1) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("field position must be greater than zero"))); start_posn = text_position(PointerGetDatum(inputstring), PointerGetDatum(fldsep), fldnum - 1); end_posn = text_position(PointerGetDatum(inputstring), PointerGetDatum(fldsep), fldnum); if ((start_posn == 0) && (end_posn == 0)) /* fldsep not found */ { if (fldnum == 1) /* first field - just return the input * string */ PG_RETURN_TEXT_P(inputstring); else/* otherwise return an empty string */ PG_RETURN_TEXT_P(PG_STR_GET_TEXT("")); } else if ((start_posn != 0) && (end_posn == 0)) { /* last field requested */ result_text = text_substring(PointerGetDatum(inputstring), start_posn + fldsep_len, -1, true); PG_RETURN_TEXT_P(result_text); } else if ((start_posn == 0) && (end_posn != 0)) { /* first field requested */ result_text = LEFT(inputstring, fldsep); PG_RETURN_TEXT_P(result_text); } else { /* prior to last field requested */ result_text = text_substring(PointerGetDatum(inputstring), start_posn + fldsep_len, end_posn - start_posn - fldsep_len, false); PG_RETURN_TEXT_P(result_text); }}/* * text_to_array * parse input string * return text array of elements * based on provided field separator */Datumtext_to_array(PG_FUNCTION_ARGS){ text *inputstring = PG_GETARG_TEXT_P(0); int inputstring_len = TEXTLEN(inputstring); text *fldsep = PG_GETARG_TEXT_P(1); int fldsep_len = TEXTLEN(fldsep); int fldnum; int start_posn = 0; int end_posn = 0; text *result_text = NULL; ArrayBuildState *astate = NULL; MemoryContext oldcontext = CurrentMemoryContext; /* return NULL for empty input string */ if (inputstring_len < 1) PG_RETURN_NULL(); /* * empty field separator return one element, 1D, array using the input * string */ if (fldsep_len < 1) PG_RETURN_ARRAYTYPE_P(create_singleton_array(fcinfo, TEXTOID, CStringGetDatum(inputstring), 1)); /* start with end position holding the initial start position */ end_posn = 0; for (fldnum = 1;; fldnum++) /* field number is 1 based */ { Datum dvalue; bool disnull = false; start_posn = end_posn; end_posn = text_position(PointerGetDatum(inputstring), PointerGetDatum(fldsep), fldnum); if ((start_posn == 0) && (end_posn == 0)) /* fldsep not found */ { if (fldnum == 1) { /* * first element return one element, 1D, array using the * input string */ PG_RETURN_ARRAYTYPE_P(create_singleton_array(fcinfo, TEXTOID, CStringGetDatum(inputstring), 1)); } else { /* otherwise create array and exit */ PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, oldcontext)); } } else if ((start_posn != 0) && (end_posn == 0)) { /* last field requested */ result_text = text_substring(PointerGetDatum(inputstring), start_posn + fldsep_len, -1, true); } else if ((start_posn == 0) && (end_posn != 0)) { /* first field requested */ result_text = LEFT(inputstring, fldsep); } else { /* prior to last field requested */ result_text = text_substring(PointerGetDatum(inputstring), start_posn + fldsep_len, end_posn - start_posn - fldsep_len, false); } /* stash away current value */ dvalue = PointerGetDatum(result_text); astate = accumArrayResult(astate, dvalue, disnull, TEXTOID, oldcontext); } /* never reached -- keep compiler quiet */ PG_RETURN_NULL();}/* * array_to_text * concatenate Cstring representation of input array elements * using provided field separator */Datumarray_to_text(PG_FUNCTION_ARGS){ ArrayType *v = PG_GETARG_ARRAYTYPE_P(0); char *fldsep = PG_TEXTARG_GET_STR(1); int nitems, *dims, ndims; char *p; Oid element_type; int typlen; bool typbyval; char typalign; Oid typelem; StringInfo result_str = makeStringInfo(); int i; ArrayMetaState *my_extra; p = ARR_DATA_PTR(v); ndims = ARR_NDIM(v); dims = ARR_DIMS(v); nitems = ArrayGetNItems(ndims, dims); /* if there are no elements, return an empty string */ if (nitems == 0) PG_RETURN_TEXT_P(PG_STR_GET_TEXT("")); element_type = ARR_ELEMTYPE(v); /* * We arrange to look up info about element type, including its output * conversion proc, only once per series of calls, assuming the * element type doesn't change underneath us. */ my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; if (my_extra == NULL) { fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(ArrayMetaState)); my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; my_extra->element_type = InvalidOid; } if (my_extra->element_type != element_type) { /* * Get info about element type, including its output conversion * proc */ get_type_io_data(element_type, IOFunc_output, &my_extra->typlen, &my_extra->typbyval, &my_extra->typalign, &my_extra->typdelim, &my_extra->typelem, &my_extra->typiofunc); fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc, fcinfo->flinfo->fn_mcxt); my_extra->element_type = element_type; } typlen = my_extra->typlen; typbyval = my_extra->typbyval; typalign = my_extra->typalign; typelem = my_extra->typelem; for (i = 0; i < nitems; i++) { Datum itemvalue; char *value; itemvalue = fetch_att(p, typbyval, typlen); value = DatumGetCString(FunctionCall3(&my_extra->proc, itemvalue, ObjectIdGetDatum(typelem), Int32GetDatum(-1))); if (i > 0) appendStringInfo(result_str, "%s%s", fldsep, value); else appendStringInfo(result_str, "%s", value); p = att_addlength(p, typlen, PointerGetDatum(p)); p = (char *) att_align(p, typalign); } PG_RETURN_TEXT_P(PG_STR_GET_TEXT(result_str->data));}#define HEXBASE 16/* * Convert a int32 to a string containing a base 16 (hex) representation of * the number. */Datumto_hex32(PG_FUNCTION_ARGS){ uint32 value = (uint32) PG_GETARG_INT32(0); text *result_text; char *ptr; const char *digits = "0123456789abcdef"; char buf[32]; /* bigger than needed, but reasonable */ ptr = buf + sizeof(buf) - 1; *ptr = '\0'; do { *--ptr = digits[value % HEXBASE]; value /= HEXBASE; } while (ptr > buf && value); result_text = PG_STR_GET_TEXT(ptr); PG_RETURN_TEXT_P(result_text);}/* * Convert a int64 to a string containing a base 16 (hex) representation of * the number. */Datumto_hex64(PG_FUNCTION_ARGS){ uint64 value = (uint64) PG_GETARG_INT64(0); text *result_text; char *ptr; const char *digits = "0123456789abcdef"; char buf[32]; /* bigger than needed, but reasonable */ ptr = buf + sizeof(buf) - 1; *ptr = '\0'; do { *--ptr = digits[value % HEXBASE]; value /= HEXBASE; } while (ptr > buf && value); result_text = PG_STR_GET_TEXT(ptr); PG_RETURN_TEXT_P(result_text);}/* * Create an md5 hash of a text string and return it as hex * * md5 produces a 16 byte (128 bit) hash; double it for hex */#define MD5_HASH_LEN 32Datummd5_text(PG_FUNCTION_ARGS){ char *buff = PG_TEXT_GET_STR(PG_GETARG_TEXT_P(0)); size_t len = strlen(buff); char *hexsum; text *result_text; /* leave room for the terminating '\0' */ hexsum = (char *) palloc(MD5_HASH_LEN + 1); /* get the hash result */ md5_hash((void *) buff, len, hexsum); /* convert to text and return it */ result_text = PG_STR_GET_TEXT(hexsum); PG_RETURN_TEXT_P(result_text);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?