Beispiel #1
0
/*
 * Convert a C string to VARCHAR internal representation.  atttypmod
 * is the declared length of the type plus VARHDRSZ.
 */
Datum
varcharin(PG_FUNCTION_ARGS)
{
	char	   *s = PG_GETARG_CSTRING(0);

#ifdef NOT_USED
	Oid			typelem = PG_GETARG_OID(1);
#endif
	int32		atttypmod = PG_GETARG_INT32(2);
	VarChar    *result;

	result = varchar_input(s, strlen(s), atttypmod);
	PG_RETURN_VARCHAR_P(result);
}
Beispiel #2
0
/*
 * Input.
 */
Datum
json_in(PG_FUNCTION_ARGS)
{
	char	   *json = PG_GETARG_CSTRING(0);
	text	   *result = cstring_to_text(json);
	JsonLexContext *lex;

	/* validate it */
	lex = makeJsonLexContext(result, false);
	pg_parse_json(lex, NullSemAction);

	/* Internal representation is the same as text, for now */
	PG_RETURN_TEXT_P(result);
}
Beispiel #3
0
Datum
win866_to_win1251(PG_FUNCTION_ARGS)
{
	unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
	unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
	int			len = PG_GETARG_INT32(4);
	unsigned char *buf;

	CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_WIN1251);

	/*
	 * Note: There are a few characters like the "Numero" sign that exist in
	 * all the other cyrillic encodings (win1251, ISO_8859-5 and cp866), but
	 * not in KOI8R. As we use MULE_INTERNAL/KOI8R as an intermediary, we will
	 * fail to convert those characters.
	 */
	buf = palloc(len * ENCODING_GROWTH_RATE + 1);
	win8662mic(src, buf, len);
	mic2win1251(buf, dest, strlen((char *) buf));
	pfree(buf);

	PG_RETURN_VOID();
}
Beispiel #4
0
Datum
smgrin(PG_FUNCTION_ARGS)
{
	char	   *s = PG_GETARG_CSTRING(0);
	int16		i;

	for (i = 0; i < NStorageManagers; i++)
	{
		if (strcmp(s, StorageManager[i].smgr_name) == 0)
			PG_RETURN_INT16(i);
	}
	elog(ERROR, "unrecognized storage manager name \"%s\"", s);
	PG_RETURN_INT16(0);
}
Beispiel #5
0
Datum
utf8_to_iso8859_1(PG_FUNCTION_ARGS)
{
	unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
	unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
	int			len = PG_GETARG_INT32(4);
	unsigned short c,
				c1,
				c2;

	Assert(PG_GETARG_INT32(0) == PG_UTF8);
	Assert(PG_GETARG_INT32(1) == PG_LATIN1);
	Assert(len >= 0);

	while (len >= 0 && (c = *src++))
	{
		if ((c & 0xe0) == 0xc0)
		{
			c1 = c & 0x1f;
			c2 = *src++ & 0x3f;
			*dest = c1 << 6;
			*dest++ |= c2;
			len -= 2;
		}
		else if ((c & 0xe0) == 0xe0)
			elog(ERROR, "could not convert UTF8 character 0x%04x to ISO8859-1",
				 c);
		else
		{
			*dest++ = c;
			len--;
		}
	}
	*dest = '\0';

	PG_RETURN_VOID();
}
Datum geography_in(PG_FUNCTION_ARGS)
{
	char *str = PG_GETARG_CSTRING(0);
	/* Datum geog_oid = PG_GETARG_OID(1); Not needed. */
	int32 geog_typmod = -1;
	LWGEOM_PARSER_RESULT lwg_parser_result;
	LWGEOM *lwgeom = NULL;
	GSERIALIZED *g_ser = NULL;

	if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
		geog_typmod = PG_GETARG_INT32(2);
	}

	lwgeom_parser_result_init(&lwg_parser_result);

	/* Empty string. */
	if ( str[0] == '\0' )
		ereport(ERROR,(errmsg("parse error - invalid geometry")));

	/* WKB? Let's find out. */
	if ( str[0] == '0' )
	{
		/* TODO: 20101206: No parser checks! This is inline with current 1.5 behavior, but needs discussion */
		lwgeom = lwgeom_from_hexwkb(str, LW_PARSER_CHECK_NONE);
		/* Error out if something went sideways */
		if ( ! lwgeom ) 
			ereport(ERROR,(errmsg("parse error - invalid geometry")));
	}
	/* WKT then. */
	else
	{
		if ( lwgeom_parse_wkt(&lwg_parser_result, str, LW_PARSER_CHECK_ALL) == LW_FAILURE )
			PG_PARSER_ERROR(lwg_parser_result);

		lwgeom = lwg_parser_result.geom;
	}

	/* Error on any SRID != default */
	srid_is_latlong(fcinfo, lwgeom->srid);
	
	/* Convert to gserialized */
	g_ser = gserialized_geography_from_lwgeom(lwgeom, geog_typmod);

	/* Clean up temporary object */
	lwgeom_free(lwgeom);


	PG_RETURN_POINTER(g_ser);
}
Beispiel #7
0
/*
 *		reltimein		- converts a reltime string in an internal format
 */
Datum
reltimein(PG_FUNCTION_ARGS)
{
	char	   *str = PG_GETARG_CSTRING(0);
	RelativeTime result;
	struct pg_tm tt,
			   *tm = &tt;
	fsec_t		fsec;
	int			dtype;
	int			dterr;
	char	   *field[MAXDATEFIELDS];
	int			nf,
				ftype[MAXDATEFIELDS];
	char		workbuf[MAXDATELEN + 1];

	dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
						  field, ftype, MAXDATEFIELDS, &nf);
	if (dterr == 0)
		dterr = DecodeInterval(field, ftype, nf, INTERVAL_FULL_RANGE,
							   &dtype, tm, &fsec);

	/* if those functions think it's a bad format, try ISO8601 style */
	if (dterr == DTERR_BAD_FORMAT)
		dterr = DecodeISO8601Interval(str,
									  &dtype, tm, &fsec);

	if (dterr != 0)
	{
		if (dterr == DTERR_FIELD_OVERFLOW)
			dterr = DTERR_INTERVAL_OVERFLOW;
		DateTimeParseError(dterr, str, "reltime");
	}

	switch (dtype)
	{
		case DTK_DELTA:
			result = ((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec;
			result += tm->tm_year * SECS_PER_YEAR + ((tm->tm_mon * DAYS_PER_MONTH) + tm->tm_mday) * SECS_PER_DAY;
			break;

		default:
			elog(ERROR, "unexpected dtype %d while parsing reltime \"%s\"",
				 dtype, str);
			result = INVALID_RELTIME;
			break;
	}

	PG_RETURN_RELATIVETIME(result);
}
Beispiel #8
0
Datum
seg_in(PG_FUNCTION_ARGS)
{
	char	   *str = PG_GETARG_CSTRING(0);
	SEG		   *result = palloc(sizeof(SEG));

	seg_scanner_init(str);

	if (seg_yyparse(result) != 0)
		seg_yyerror(result, "bogus input");

	seg_scanner_finish();

	PG_RETURN_POINTER(result);
}
Beispiel #9
0
/*
 *		namein	- converts "..." to internal representation
 *
 *		Note:
 *				[Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
 *				Now, always NULL terminated
 */
Datum
namein(PG_FUNCTION_ARGS)
{
    char	   *s = PG_GETARG_CSTRING(0);
    NameData   *result;
    int			len;

    len = strlen(s);
    len = pg_mbcliplen(s, len, NAMEDATALEN - 1);

    result = (NameData *) palloc0(NAMEDATALEN);
    memcpy(NameStr(*result), s, len);

    PG_RETURN_NAME(result);
}
Beispiel #10
0
Datum timeIndeterminateType_in( PG_FUNCTION_ARGS )
{
	try
	{
		int4 ret = indeterminate[ PG_GETARG_CSTRING( 0 ) ];
		PG_RETURN_INT32( ret );
	}
	catch ( std::out_of_range & e )
	{
		ereport( ERROR,
	             ( errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
	               errmsg( e.what() )));
	}
	PG_RETURN_NULL(); // Never reached
}
Beispiel #11
0
/* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */
Datum
cube_in(PG_FUNCTION_ARGS)
{
	char	   *str = PG_GETARG_CSTRING(0);
	void	   *result;

	cube_scanner_init(str);

	if (cube_yyparse(&result) != 0)
		cube_yyerror("bogus input");

	cube_scanner_finish();

	PG_RETURN_NDBOX(result);
}
Beispiel #12
0
Datum mol_adjust_query_properties(PG_FUNCTION_ARGS) {
  CROMol mol;
  fcinfo->flinfo->fn_extra =
      searchMolCache(fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt,
                     PG_GETARG_DATUM(0), NULL, &mol, NULL);
  Assert(mol != 0);
  char *data = PG_GETARG_CSTRING(1);

  CROMol adj = MolAdjustQueryProperties(mol, data);
  if (!adj) PG_RETURN_NULL();
  Mol *res = deconstructROMol(adj);
  freeCROMol(adj);

  PG_RETURN_MOL_P(res);
}
Beispiel #13
0
/*
 * get_and_purge_connection first gets a connection using the provided hostname
 * and port before immediately passing that connection to PurgeConnection.
 * Simply a wrapper around PurgeConnection that uses hostname/port rather than
 * PGconn.
 */
Datum
get_and_purge_connection(PG_FUNCTION_ARGS)
{
	char *nodeName = PG_GETARG_CSTRING(0);
	int32 nodePort = PG_GETARG_INT32(1);

	PGconn *connection = GetOrEstablishConnection(nodeName, nodePort);
	if (connection == NULL)
	{
		PG_RETURN_BOOL(false);
	}

	PurgeConnection(connection);

	PG_RETURN_BOOL(true);
}
Beispiel #14
0
/* ----------------------------------------------------------------
 *		tidin
 * ----------------------------------------------------------------
 */
Datum
tidin(PG_FUNCTION_ARGS)
{
	char	   *str = PG_GETARG_CSTRING(0);
	char	   *p,
			   *coord[NTIDARGS];
	int			i;
	ItemPointer result;
	BlockNumber blockNumber;
	OffsetNumber offsetNumber;
	char	   *badp;
	int			hold_offset;

	for (i = 0, p = str; *p && i < NTIDARGS && *p != RDELIM; p++)
		if (*p == DELIM || (*p == LDELIM && !i))
			coord[i++] = p + 1;

	if (i < NTIDARGS)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("invalid input syntax for type tid: \"%s\"",
						str)));

	errno = 0;
	blockNumber = strtoul(coord[0], &badp, 10);
	if (errno || *badp != DELIM)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("invalid input syntax for type tid: \"%s\"",
						str)));

	hold_offset = strtol(coord[1], &badp, 10);
	if (errno || *badp != RDELIM ||
		hold_offset > USHRT_MAX || hold_offset < 0)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("invalid input syntax for type tid: \"%s\"",
						str)));

	offsetNumber = hold_offset;

	result = (ItemPointer) palloc(sizeof(ItemPointerData));

	ItemPointerSet(result, blockNumber, offsetNumber);

	PG_RETURN_ITEMPOINTER(result);
}
Beispiel #15
0
Datum htg_in(PG_FUNCTION_ARGS){
	char *str = PG_GETARG_CSTRING(0);
	char buffer[30];
	VALH temp;
	Histogram *result;
	
	generateHistogram(str);
	//memcpy(result->path,str,256);

	str = strcat(str,".htg");
	FILE * hgrFile = fopen(str,"r");
	

	if(hgrFile == NULL){
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("invalid input syntax for histogram: \"%s\" The file doesn't exist",
						str)));
	}
	
	result = (Histogram *) palloc(sizeof(Histogram));

	for(int i = 0; i < HTG_SIZE; i++){	
		fgets(buffer,31,hgrFile);	
		sscanf(buffer, "%d", &temp);
		result->htg[i] = temp;
		
	}

	fclose(hgrFile);

	char * comp2 = (char*) palloc(strlen(str) + 3 + 5);
	comp2 = strcpy(comp2,"rm ");
	comp2 = strcat(comp2,str);
	Counter e = system(comp2);
	
	if(e == -1){
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("The histogram doesn't generate")));	
	}

	result->radius = 0;

	PG_RETURN_POINTER(result);
}
Beispiel #16
0
/*
 * get_and_purge_connection first gets a connection using the provided hostname
 * and port before immediately passing that connection to PurgeConnection. This
 * is to test PurgeConnection behvaior when circumventing the cache.
 */
Datum
connect_and_purge_connection(PG_FUNCTION_ARGS)
{
	char *nodeName = PG_GETARG_CSTRING(0);
	int32 nodePort = PG_GETARG_INT32(1);
	char *nodeUser = CurrentUserName();

	PGconn *connection = ConnectToNode(nodeName, nodePort, nodeUser);
	if (connection == NULL)
	{
		PG_RETURN_BOOL(false);
	}

	PurgeConnection(connection);

	PG_RETURN_BOOL(true);
}
Beispiel #17
0
Datum
hstore_in(PG_FUNCTION_ARGS)
{
	HSParser	state;
	int4		buflen;
	HStore	   *out;

	state.begin = PG_GETARG_CSTRING(0);

	parse_hstore(&state);

	state.pcur = hstoreUniquePairs(state.pairs, state.pcur, &buflen);

	out = hstorePairs(state.pairs, state.pcur, buflen);

	PG_RETURN_POINTER(out);
}
Beispiel #18
0
/*
 * to_regtype		- converts "typename" to type OID
 *
 * If the name is not found, we return NULL.
 */
Datum
to_regtype(PG_FUNCTION_ARGS)
{
	char	   *typ_name = PG_GETARG_CSTRING(0);
	Oid			result;
	int32		typmod;

	/*
	 * Invoke the full parser to deal with special cases such as array syntax.
	 */
	parseTypeString(typ_name, &result, &typmod, true);

	if (OidIsValid(result))
		PG_RETURN_OID(result);
	else
		PG_RETURN_NULL();
}
Beispiel #19
0
Datum
xmlnode_in(PG_FUNCTION_ARGS)
{
	pg_enc		dbEnc;
	XMLNodeParserStateData parserState;
	char	   *input = PG_GETARG_CSTRING(0);

	if (strlen(input) == 0)
	{
		elog(ERROR, "zero length input string");
	}
	dbEnc = GetDatabaseEncoding();
	initXMLParserState(&parserState, input, false);
	xmlnodeParseNode(&parserState);
	finalizeXMLParserState(&parserState);
	PG_RETURN_POINTER(parserState.result);
}
Beispiel #20
0
Datum
int44in(PG_FUNCTION_ARGS)
{
	char	   *input_string = PG_GETARG_CSTRING(0);
	int32	   *result = (int32 *) palloc(4 * sizeof(int32));
	int			i;

	i = sscanf(input_string,
			   "%d, %d, %d, %d",
			   &result[0],
			   &result[1],
			   &result[2],
			   &result[3]);
	while (i < 4)
		result[i++] = 0;

	PG_RETURN_POINTER(result);
}
Beispiel #21
0
Datum
reverse_name(PG_FUNCTION_ARGS)
{
	char	   *string = PG_GETARG_CSTRING(0);
	int			i;
	int			len;
	char	   *new_string;

	new_string = palloc0(NAMEDATALEN);
	for (i = 0; i < NAMEDATALEN && string[i]; ++i)
		;
	if (i == NAMEDATALEN || !string[i])
		--i;
	len = i;
	for (; i >= 0; --i)
		new_string[len - i] = string[i];
	PG_RETURN_CSTRING(new_string);
}
Beispiel #22
0
/* ----------------------------------------------------------------
 *		gpxloglocin
 * ----------------------------------------------------------------
 */
Datum
gpxloglocin(PG_FUNCTION_ARGS)
{
	char	   *str = PG_GETARG_CSTRING(0);
	char	   *p,
			   *coord[NXLOGLOCARGS];
	int			i;
	XLogRecPtr	*result;
	uint32		result_xlogid;
	uint32		result_xrecoff;
	char	   *badp;

	for (i = 0, p = str; *p && i < NXLOGLOCARGS && *p != RDELIM; p++)
		if (*p == DELIM || (*p == LDELIM && !i))
			coord[i++] = p + 1;

	if (i < NXLOGLOCARGS)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("invalid input syntax for type gpxlogloc: \"%s\"",
						str)));

	errno = 0;
	result_xlogid = strtoul(coord[0], &badp, 16);	// Hexadecimal.
	if (errno || *badp != DELIM)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("invalid input syntax for type gpxlogloc: \"%s\"",
						str)));

	result_xrecoff = strtoul(coord[1], &badp, 16);	// Hexadecimal.
	if (errno || *badp != RDELIM)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("invalid input syntax for type gpxlogloc: \"%s\"",
						str)));

	result = (XLogRecPtr*) palloc(sizeof(XLogRecPtr));

	result->xlogid = result_xlogid;
	result->xrecoff = result_xrecoff;

	PG_RETURN_XLOGLOC(result);
}
Beispiel #23
0
Datum
chkpass_in(PG_FUNCTION_ARGS)
{
	char	   *str = PG_GETARG_CSTRING(0);
	chkpass    *result;
	char		mysalt[4];
	char	   *crypt_output;
	static char salt_chars[] =
	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

	/* special case to let us enter encrypted passwords */
	if (*str == ':')
	{
		result = (chkpass *) palloc0(sizeof(chkpass));
		strlcpy(result->password, str + 1, 13 + 1);
		PG_RETURN_POINTER(result);
	}

	if (verify_pass(str) != 0)
		ereport(ERROR,
				(errcode(ERRCODE_DATA_EXCEPTION),
				 errmsg("password \"%s\" is weak", str)));

	result = (chkpass *) palloc0(sizeof(chkpass));

	if (!pg_backend_random(mysalt, 2))
		ereport(ERROR,
				(errmsg("could not generate random salt")));

	mysalt[0] = salt_chars[mysalt[0] & 0x3f];
	mysalt[1] = salt_chars[mysalt[1] & 0x3f];
	mysalt[2] = 0;				/* technically the terminator is not necessary
								 * but I like to play safe */

	crypt_output = crypt(str, mysalt);
	if (crypt_output == NULL)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("crypt() failed")));

	strlcpy(result->password, crypt_output, sizeof(result->password));

	PG_RETURN_POINTER(result);
}
Beispiel #24
0
Datum
complex_in(PG_FUNCTION_ARGS)
{
	char	   *str = PG_GETARG_CSTRING(0);
	double		x,
				y;
	Complex    *result;

	if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
				 errmsg("invalid input syntax for complex: \"%s\"",
						str)));

	result = (Complex *) palloc(sizeof(Complex));
	result->x = x;
	result->y = y;
	PG_RETURN_POINTER(result);
}
Beispiel #25
0
Datum
spheretrans_in(PG_FUNCTION_ARGS)
{
	SEuler	   *se = (SEuler *) palloc(sizeof(SEuler));
	char	   *c = PG_GETARG_CSTRING(0);
	unsigned char etype[3];
	int			i;

	void		sphere_yyparse(void);

	init_buffer(c);
	sphere_yyparse();

	if (get_euler(&se->phi, &se->theta, &se->psi, etype))
	{

		for (i = 0; i < 3; i++)
		{
			switch (i)
			{
				case 0:
					se->phi_a = etype[i];
					break;
				case 1:
					se->theta_a = etype[i];
					break;
				case 2:
					se->psi_a = etype[i];
					break;
			}
		}
		spheretrans_check(se);
	}
	else
	{
		reset_buffer();
		pfree(se);
		se = NULL;
		elog(ERROR, "spheretrans_in: parse error");
	}
	reset_buffer();
	PG_RETURN_POINTER(se);
}
Beispiel #26
0
/*
 *		namein	- converts "..." to internal representation
 *
 *		Note:
 *				[Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
 *				Now, always NULL terminated
 */
Datum
namein(PG_FUNCTION_ARGS)
{
	char	   *s = PG_GETARG_CSTRING(0);
	Name		result;
	int			len;

	len = strlen(s);

	/* Truncate oversize input */
	if (len >= NAMEDATALEN)
		len = pg_mbcliplen(s, len, NAMEDATALEN - 1);

	/* We use palloc0 here to ensure result is zero-padded */
	result = (Name) palloc0(NAMEDATALEN);
	memcpy(NameStr(*result), s, len);

	PG_RETURN_NAME(result);
}
Beispiel #27
0
/*
 * to_regoper		- converts "oprname" to operator OID
 *
 * If the name is not found, we return NULL.
 */
Datum
to_regoper(PG_FUNCTION_ARGS)
{
	char	   *opr_name = PG_GETARG_CSTRING(0);
	List	   *names;
	FuncCandidateList clist;

	/*
	 * Parse the name into components and see if it matches any pg_operator
	 * entries in the current search path.
	 */
	names = stringToQualifiedNameList(opr_name);
	clist = OpernameGetCandidates(names, '\0', true);

	if (clist == NULL || clist->next != NULL)
		PG_RETURN_NULL();

	PG_RETURN_OID(clist->oid);
}
Beispiel #28
0
/*
 * to_regproc	- converts "proname" to proc OID
 *
 * If the name is not found, we return NULL.
 */
Datum
to_regproc(PG_FUNCTION_ARGS)
{
	char	   *pro_name = PG_GETARG_CSTRING(0);
	List	   *names;
	FuncCandidateList clist;

	/*
	 * Parse the name into components and see if it matches any pg_proc
	 * entries in the current search path.
	 */
	names = stringToQualifiedNameList(pro_name);
	clist = FuncnameGetCandidates(names, -1, NIL, false, false, true);

	if (clist == NULL || clist->next != NULL)
		PG_RETURN_NULL();

	PG_RETURN_OID(clist->oid);
}
Beispiel #29
0
Datum
xmldoc_in(PG_FUNCTION_ARGS)
{
	pg_enc		dbEnc;
	XMLNodeParserStateData parserState;
	char	   *input = PG_GETARG_CSTRING(0);

	if (strlen(input) == 0)
	{
		elog(ERROR, "zero length input string");
	}
	dbEnc = GetDatabaseEncoding();
	if (dbEnc != PG_UTF8)
	{
		elog(ERROR, "The current version of xmlnode requires both database encoding to be UTF-8.");
	}
	initXMLParserState(&parserState, input, false);
	xmlnodeParseDoc(&parserState);
	finalizeXMLParserState(&parserState);
	PG_RETURN_POINTER(parserState.result);
}
Beispiel #30
0
/*
 * to_regclass		- converts "classname" to class OID
 *
 * If the name is not found, we return NULL.
 */
Datum
to_regclass(PG_FUNCTION_ARGS)
{
	char	   *class_name = PG_GETARG_CSTRING(0);
	Oid			result;
	List	   *names;

	/*
	 * Parse the name into components and see if it matches any pg_class
	 * entries in the current search path.
	 */
	names = stringToQualifiedNameList(class_name);

	/* We might not even have permissions on this relation; don't lock it. */
	result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, true);

	if (OidIsValid(result))
		PG_RETURN_OID(result);
	else
		PG_RETURN_NULL();
}