Datum pgstattuple(PG_FUNCTION_ARGS) { text *relname = PG_GETARG_TEXT_P(0); RangeVar *relrv; Relation rel; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use pgstattuple functions")))); /* open relation */ relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = relation_openrv(relrv, AccessShareLock); PG_RETURN_DATUM(pgstat_relation(rel, fcinfo)); }
Datum text2ltree(PG_FUNCTION_ARGS) { text *in = PG_GETARG_TEXT_P(0); char *s = (char *) palloc(VARSIZE(in) - VARHDRSZ + 1); ltree *out; memcpy(s, VARDATA(in), VARSIZE(in) - VARHDRSZ); s[VARSIZE(in) - VARHDRSZ] = '\0'; out = (ltree *) DatumGetPointer(DirectFunctionCall1( ltree_in, PointerGetDatum(s) )); pfree(s); PG_FREE_IF_COPY(in, 0); PG_RETURN_POINTER(out); }
Datum text_char(PG_FUNCTION_ARGS) { text *arg1 = PG_GETARG_TEXT_P(0); char result; /* * An empty input string is converted to \0 (for consistency with * charin). If the input is longer than one character, the excess data * is silently discarded. */ if (VARSIZE(arg1) > VARHDRSZ) result = *(VARDATA(arg1)); else result = '\0'; PG_RETURN_CHAR(result); }
Datum pg_decrypt(PG_FUNCTION_ARGS) { int err; bytea *data, *key, *res; text *type; PX_Combo *c; unsigned dlen, klen, rlen; type = PG_GETARG_TEXT_P(2); c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); data = PG_GETARG_BYTEA_P(0); key = PG_GETARG_BYTEA_P(1); dlen = VARSIZE(data) - VARHDRSZ; klen = VARSIZE(key) - VARHDRSZ; rlen = px_combo_decrypt_len(c, dlen); res = palloc(VARHDRSZ + rlen); err = px_combo_init(c, (uint8 *) VARDATA(key), klen, NULL, 0); if (!err) err = px_combo_decrypt(c, (uint8 *) VARDATA(data), dlen, (uint8 *) VARDATA(res), &rlen); px_combo_free(c); if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("decrypt error: %s", px_strerror(err)))); SET_VARSIZE(res, VARHDRSZ + rlen); PG_FREE_IF_COPY(data, 0); PG_FREE_IF_COPY(key, 1); PG_FREE_IF_COPY(type, 2); PG_RETURN_BYTEA_P(res); }
Datum headline_byname(PG_FUNCTION_ARGS) { text *cfg = PG_GETARG_TEXT_P(0); Datum out; SET_FUNCOID(); out = DirectFunctionCall4( headline, ObjectIdGetDatum(name2id_cfg(cfg)), PG_GETARG_DATUM(1), PG_GETARG_DATUM(2), (PG_NARGS() > 3) ? PG_GETARG_DATUM(3) : PointerGetDatum(NULL) ); PG_FREE_IF_COPY(cfg, 0); PG_RETURN_DATUM(out); }
/* fwrite(encode(args[n], encoding), f) */ static int do_write(PG_FUNCTION_ARGS, int n, FILE *f, int max_linesize, int encoding) { text *arg = PG_GETARG_TEXT_P(n); char *str; int len; str = encode_text(encoding, arg, &len); CHECK_LENGTH(len); if (fwrite(str, 1, len, f) != len) CHECK_ERRNO_PUT(); if (VARDATA(arg) != str) pfree(str); PG_FREE_IF_COPY(arg, n); return len; }
Datum to_tsquery_byid(PG_FUNCTION_ARGS) { Oid cfgid = PG_GETARG_OID(0); text *in = PG_GETARG_TEXT_P(1); TSQuery query; QueryItem *res; int4 len; query = parse_tsquery(text_to_cstring(in), pushval_morph, ObjectIdGetDatum(cfgid), false); if (query->size == 0) PG_RETURN_TSQUERY(query); /* clean out any stopword placeholders from the tree */ res = clean_fakeval(GETQUERY(query), &len); if (!res) { SET_VARSIZE(query, HDRSIZETQ); query->size = 0; PG_RETURN_POINTER(query); } memcpy((void *) GETQUERY(query), (void *) res, len * sizeof(QueryItem)); /* * Removing the stopword placeholders might've resulted in fewer * QueryItems. If so, move the operands up accordingly. */ if (len != query->size) { char *oldoperand = GETOPERAND(query); int4 lenoperand = VARSIZE(query) - (oldoperand - (char *) query); Assert(len < query->size); query->size = len; memmove((void *) GETOPERAND(query), oldoperand, VARSIZE(query) - (oldoperand - (char *) query)); SET_VARSIZE(query, COMPUTESIZE(len, lenoperand)); } pfree(res); PG_RETURN_TSQUERY(query); }
Datum domainname_parts(PG_FUNCTION_ARGS) { text *in = PG_GETARG_TEXT_P(0); const char *s = VARDATA(in); const char *b = s, *p = s, *e = s + VARSIZE_ANY_EXHDR(in); int nelems = 0; int nbytes = ARR_OVERHEAD_NONULLS(1); ArrayType *r; char *o; while (p < e) { b = p; STRSEARCH(p, e-p, *p == '.'); nelems ++; nbytes += VARHDRSZ + (p-b); nbytes = INTALIGN(nbytes); p ++; } r = (ArrayType *)palloc(nbytes); SET_VARSIZE(r, nbytes); r->ndim = 1; r->dataoffset = 0; r->elemtype = TEXTOID; *ARR_DIMS(r) = nelems; *ARR_LBOUND(r) = 1; p = s; o = ARR_DATA_PTR(r); while (p < e) { b = p; STRSEARCH(p, e-p, *p == '.'); SET_VARSIZE(o, VARHDRSZ+(p-b)); o = VARDATA(o); memcpy(o, b, p-b); o += INTALIGN(p-b); p ++; } PG_FREE_IF_COPY(in, 0); PG_RETURN_ARRAYTYPE_P(r); }
Datum text_int4(PG_FUNCTION_ARGS) { text *string = PG_GETARG_TEXT_P(0); Datum result; int len; char *str; len = VARSIZE(string) - VARHDRSZ; str = palloc(len + 1); memcpy(str, VARDATA(string), len); *(str + len) = '\0'; result = DirectFunctionCall1(int4in, CStringGetDatum(str)); pfree(str); return result; }
Datum OptimizeMinidumpFromFile(PG_FUNCTION_ARGS) { char *szFileName = textToString(PG_GETARG_TEXT_P(0)); char *szResultDXL = COptTasks::SzOptimizeMinidumpFromFile(szFileName); if (NULL != szResultDXL) { text *ptResult = stringToText(szResultDXL); gpdb::GPDBFree(szResultDXL); PG_RETURN_TEXT_P(ptResult); } else { elog(NOTICE, "Execution of UDF 'OptimizeMinidumpFromFile' failed. Consult the LOG for more information."); // return a dummy value PG_RETURN_NULL(); } }
/* * text_float4 - converts a text string to a float4 number */ Datum text_float4(PG_FUNCTION_ARGS) { text *string = PG_GETARG_TEXT_P(0); Datum result; int len; char *str; len = (VARSIZE(string) - VARHDRSZ); str = palloc(len + 1); memcpy(str, VARDATA(string), len); *(str + len) = '\0'; result = DirectFunctionCall1(float4in, CStringGetDatum(str)); pfree(str); PG_RETURN_DATUM(result); }
Datum Optimize(PG_FUNCTION_ARGS) { char *szSQLText = textToString(PG_GETARG_TEXT_P(0)); Query *pquery = parseSQL(szSQLText); Query *pqueryNormalized = preprocess_query_optimizer(pquery, NULL); Assert(pqueryNormalized); char *szOutput = COptTasks::SzOptimize(pqueryNormalized); if (NULL == szOutput) { elog(ERROR, "Error optimizing query"); } PG_RETURN_TEXT_P(stringToText(szOutput)); }
Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM *lwgeom; char *hexwkb; size_t hexwkb_size; uint8_t variant = 0; text *result; text *type; size_t text_size; /* If user specified endianness, respect it */ if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) ) { type = PG_GETARG_TEXT_P(1); if ( ! strncmp(VARDATA(type), "xdr", 3) || ! strncmp(VARDATA(type), "XDR", 3) ) { variant = variant | WKB_XDR; } else { variant = variant | WKB_NDR; } } /* Create WKB hex string */ lwgeom = lwgeom_from_gserialized(geom); hexwkb = lwgeom_to_hexwkb(lwgeom, variant | WKB_EXTENDED, &hexwkb_size); lwgeom_free(lwgeom); /* Prepare the PgSQL text return type */ text_size = hexwkb_size - 1 + VARHDRSZ; result = palloc(text_size); memcpy(VARDATA(result), hexwkb, hexwkb_size - 1); SET_VARSIZE(result, text_size); /* Clean up and return */ pfree(hexwkb); PG_FREE_IF_COPY(geom, 0); PG_RETURN_TEXT_P(result); }
/* * pg_start_backup: set up for taking an on-line backup dump * * Essentially what this does is to create a backup label file in $PGDATA, * where it will be archived as part of the backup dump. The label file * contains the user-supplied label string (typically this would be used * to tell where the backup dump will be stored) and the starting time and * starting WAL location for the dump. */ Datum pg_start_backup(PG_FUNCTION_ARGS) { text *backupid = PG_GETARG_TEXT_P(0); bool fast = PG_GETARG_BOOL(1); char *backupidstr; XLogRecPtr startpoint; backupidstr = text_to_cstring(backupid); if (!superuser() && !has_rolreplication(GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or replication role to run a backup"))); startpoint = do_pg_start_backup(backupidstr, fast, NULL, NULL); PG_RETURN_LSN(startpoint); }
Datum dbms_alert_register(PG_FUNCTION_ARGS) { text *name = PG_GETARG_TEXT_P(0); int cycle = 0; float8 endtime; float8 timeout = 2; WATCH_PRE(timeout, endtime, cycle); if (ora_lock_shmem(SHMEMMSGSZ, MAX_PIPES, MAX_EVENTS, MAX_LOCKS, false)) { register_event(name); LWLockRelease(shmem_lock); PG_RETURN_VOID(); } WATCH_POST(timeout, endtime, cycle); LOCK_ERROR(); PG_RETURN_VOID(); }
Datum LWGEOM_asBinary(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; uint8_t *wkb; size_t wkb_size; bytea *result; uint8_t variant = WKB_ISO; /* Get a 2D version of the geometry */ geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); lwgeom = lwgeom_from_gserialized(geom); /* If user specified endianness, respect it */ if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) ) { text *wkb_endian = PG_GETARG_TEXT_P(1); if ( ! strncmp(VARDATA(wkb_endian), "xdr", 3) || ! strncmp(VARDATA(wkb_endian), "XDR", 3) ) { variant = variant | WKB_XDR; } else { variant = variant | WKB_NDR; } } /* Write to WKB and free the geometry */ wkb = lwgeom_to_wkb(lwgeom, variant, &wkb_size); lwgeom_free(lwgeom); /* Write to text and free the WKT */ result = palloc(wkb_size + VARHDRSZ); memcpy(VARDATA(result), wkb, wkb_size); SET_VARSIZE(result, wkb_size + VARHDRSZ); pfree(wkb); /* Return the text */ PG_FREE_IF_COPY(geom, 0); PG_RETURN_BYTEA_P(result); }
Datum hashtext(PG_FUNCTION_ARGS) { text *key = PG_GETARG_TEXT_P(0); Datum result; /* * Note: this is currently identical in behavior to hashvarlena, but * it seems likely that we may need to do something different in non-C * locales. (See also hashbpchar, if so.) */ result = hash_any((unsigned char *) VARDATA(key), VARSIZE(key) - VARHDRSZ); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(key, 0); return result; }
extern PGDLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) { #else extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) { #endif text *argv0 = PG_GETARG_TEXT_P(0); text *result_text; char *command; char *result; FILE *pipe; char *line; int32 outlen, linelen; command = text_ptr_to_char_ptr(argv0); /* Only if you want to log elog(NOTICE, "Command evaluated: %s", command); */ line = (char *)malloc(1024); result = (char *)malloc(1); outlen = 0; pipe = popen(command, "r"); while (fgets(line, sizeof(line), pipe) != NULL) { linelen = strlen(line); result = (char *)realloc(result, outlen + linelen); strncpy(result + outlen, line, linelen); outlen = outlen + linelen; } pclose(pipe); if (*result) { result[outlen-1] = 0x00; } result_text = chr_ptr_to_text_ptr(result); PG_RETURN_POINTER(result_text); }
/* * master_create_worker_shards is a user facing function to create worker shards * for the given relation in round robin order. */ Datum master_create_worker_shards(PG_FUNCTION_ARGS) { text *tableNameText = PG_GETARG_TEXT_P(0); int32 shardCount = PG_GETARG_INT32(1); int32 replicationFactor = PG_GETARG_INT32(2); Oid distributedTableId = ResolveRelationId(tableNameText); /* do not add any data */ bool useExclusiveConnections = false; EnsureCoordinator(); CheckCitusVersion(ERROR); CreateShardsWithRoundRobinPolicy(distributedTableId, shardCount, replicationFactor, useExclusiveConnections); PG_RETURN_VOID(); }
Datum copytext(PG_FUNCTION_ARGS) { text *t = PG_GETARG_TEXT_P(0); /* * VARSIZE is the total size of the struct in bytes. */ text *new_t = (text *) palloc(VARSIZE(t)); SET_VARSIZE(new_t, VARSIZE(t)); /* * VARDATA is a pointer to the data region of the struct. */ memcpy((void *) VARDATA(new_t), /* destination */ (void *) VARDATA(t), /* source */ VARSIZE(t) - VARHDRSZ); /* how many bytes */ PG_RETURN_TEXT_P(new_t); }
Datum xml_encode_special_chars(PG_FUNCTION_ARGS) { text *tin = PG_GETARG_TEXT_P(0); text *tout; xmlChar *ts, *tt; ts = pgxml_texttoxmlchar(tin); tt = xmlEncodeSpecialChars(NULL, ts); pfree(ts); tout = cstring_to_text((char *) tt); xmlFree(tt); PG_RETURN_TEXT_P(tout); }
Datum xml_valid(PG_FUNCTION_ARGS) { /* called as xml_valid(document) */ xmlDocPtr doctree; text *t = PG_GETARG_TEXT_P(0); /* document buffer */ int32 docsize = VARSIZE(t) - VARHDRSZ; pgxml_parser_init(); doctree = xmlParseMemory((char *) VARDATA(t), docsize); if (doctree == NULL) { xmlCleanupParser(); PG_RETURN_BOOL(false); /* i.e. not well-formed */ } xmlCleanupParser(); xmlFreeDoc(doctree); PG_RETURN_BOOL(true); }
Datum lexize_byname(PG_FUNCTION_ARGS) { text *dictname = PG_GETARG_TEXT_P(0); Datum res; SET_FUNCOID(); res = DirectFunctionCall3( lexize, ObjectIdGetDatum(name2id_dict(dictname)), PG_GETARG_DATUM(1), (Datum) 0 ); PG_FREE_IF_COPY(dictname, 0); if (res) PG_RETURN_DATUM(res); else PG_RETURN_NULL(); }
Datum relation_size(PG_FUNCTION_ARGS) { text *relname = PG_GETARG_TEXT_P(0); RangeVar *relrv; Relation relation; Oid relnodeOid; Oid tblspcOid; relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname, "relation_size")); relation = relation_openrv(relrv, AccessShareLock); tblspcOid = relation->rd_rel->reltablespace; relnodeOid = relation->rd_rel->relfilenode; relation_close(relation, AccessShareLock); PG_RETURN_INT64(calculate_relation_size(tblspcOid, relnodeOid)); }
Datum text_oid(PG_FUNCTION_ARGS) { text *string = PG_GETARG_TEXT_P(0); Oid result; int len; char *str; len = (VARSIZE(string) - VARHDRSZ); str = palloc(len + 1); memcpy(str, VARDATA(string), len); *(str + len) = '\0'; result = oidin_subr("text_oid", str, NULL); pfree(str); PG_RETURN_OID(result); }
Datum convert_to_internal_schema(PG_FUNCTION_ARGS) { text *schemaText = PG_GETARG_TEXT_P(0); char *schemaStr = text_to_cstring(schemaText); StringInfoData buf; initStringInfo(&buf); if (!convert_schema_type(schemaStr, HcatalogDbOid, NSPDBOID_CURRENT)) { appendStringInfo(&buf, "Schema hcatalog.%s not found!", schemaStr); } else { appendStringInfo(&buf, "Converted %s to internal schema", schemaStr); } PG_RETURN_TEXT_P(cstring_to_text(buf.data)); }
/* * quote_literal - * returns a properly quoted literal */ Datum quote_literal(PG_FUNCTION_ARGS) { text *t = PG_GETARG_TEXT_P(0); text *result; char *cp1; char *cp2; int len; len = VARSIZE(t) - VARHDRSZ; /* We make a worst-case result area; wasting a little space is OK */ result = (text *) palloc(len * 2 + 3 + VARHDRSZ); cp1 = VARDATA(t); cp2 = VARDATA(result); SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len)); PG_RETURN_TEXT_P(result); }
/* * pg_create_restore_point: a named point for restore */ Datum pg_create_restore_point(PG_FUNCTION_ARGS) { text *restore_name = PG_GETARG_TEXT_P(0); char *restore_name_str; XLogRecPtr restorepoint; char location[MAXFNAMELEN]; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to create a restore point")))); if (RecoveryInProgress()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), (errmsg("recovery is in progress"), errhint("WAL control functions cannot be executed during recovery.")))); if (!XLogIsNeeded()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("WAL level not sufficient for creating a restore point"), errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start."))); restore_name_str = text_to_cstring(restore_name); if (strlen(restore_name_str) >= MAXFNAMELEN) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("value too long for restore point (maximum %d characters)", MAXFNAMELEN - 1))); restorepoint = XLogRestorePoint(restore_name_str); /* * As a convenience, return the WAL location of the restore point record */ snprintf(location, sizeof(location), "%X/%X", restorepoint.xlogid, restorepoint.xrecoff); PG_RETURN_TEXT_P(cstring_to_text(location)); }
/* * pgespresso_start_backup: set up for taking an on-line backup dump * * Essentially what this does is to return a backup label file that the * user is responsible for placing in the $PGDATA of the backup AFTER * the backup has been taken. The label file must not be written to the * data directory of the server from which the backup is taken because * this type of backup presumes and allows that more than one backup * may be in progress at any one time. The label file * contains the user-supplied label string (typically this would be used * to tell where the backup dump will be stored) and the starting time and * starting WAL location for the dump. */ Datum pgespresso_start_backup(PG_FUNCTION_ARGS) { text *backupid = PG_GETARG_TEXT_P(0); bool fast = PG_GETARG_BOOL(1); char *backupidstr; char *labelfile; backupidstr = text_to_cstring(backupid); if (!superuser() && !has_rolreplication(GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or replication role to run a backup"))); /* * ThisTimeLineID is always 0 in a normal backend during recovery. * We get latest redo apply position timeline and we update it globally * to make do_pg_start_backup use the correct value when generating * the backup label text */ if (RecoveryInProgress()) { TimeLineID replayTLI; GetXLogReplayRecPtr(&replayTLI); ThisTimeLineID = replayTLI; elog(DEBUG1, "updated ThisTimeLineID = %u", ThisTimeLineID); } /* * Starting from 9.3 the do_pg_start_backup returns the timeline ID * in *starttli_p additional argument */ #if PG_VERSION_NUM >= 90300 do_pg_start_backup(backupidstr, fast, NULL, &labelfile); #else do_pg_start_backup(backupidstr, fast, &labelfile); #endif PG_RETURN_TEXT_P(cstring_to_text(labelfile)); }
Datum dmetaphone(PG_FUNCTION_ARGS) { text *arg, *result; int alen, rsize; char *aptr, *codes[2], *code, *rptr; #ifdef DMETAPHONE_NOSTRICT if (PG_ARGISNULL(0)) PG_RETURNNULL(); #endif arg = PG_GETARG_TEXT_P(0); alen = VARSIZE(arg) - VARHDRSZ; /* * Postgres' string values might not have trailing nuls. The VARSIZE will * not include the nul in any case so we copy things out and add a * trailing nul. When we copy back we ignore the nul (and we don't make * space for it). */ aptr = palloc(alen + 1); memcpy(aptr, VARDATA(arg), alen); aptr[alen] = 0; DoubleMetaphone(aptr, codes); code = codes[0]; if (!code) code = ""; rsize = VARHDRSZ + strlen(code); result = (text *) palloc(rsize); memset(result, 0, rsize); rptr = VARDATA(result); memcpy(rptr, code, strlen(code)); VARATT_SIZEP(result) = rsize; PG_RETURN_TEXT_P(result); }