예제 #1
0
파일: funcapi.c 프로젝트: mjw56/postgres
/*
 * get_type_func_class
 *		Given the type OID, obtain its TYPEFUNC classification.
 *
 * This is intended to centralize a bunch of formerly ad-hoc code for
 * classifying types.  The categories used here are useful for deciding
 * how to handle functions returning the datatype.
 */
static TypeFuncClass
get_type_func_class(Oid typid)
{
	switch (get_typtype(typid))
	{
		case TYPTYPE_COMPOSITE:
			return TYPEFUNC_COMPOSITE;
		case TYPTYPE_BASE:
		case TYPTYPE_DOMAIN:
		case TYPTYPE_ENUM:
			return TYPEFUNC_SCALAR;
		case TYPTYPE_PSEUDO:
			if (typid == RECORDOID)
				return TYPEFUNC_RECORD;

			/*
			 * We treat VOID and CSTRING as legitimate scalar datatypes,
			 * mostly for the convenience of the JDBC driver (which wants to
			 * be able to do "SELECT * FROM foo()" for all legitimately
			 * user-callable functions).
			 */
			if (typid == VOIDOID || typid == CSTRINGOID)
				return TYPEFUNC_SCALAR;
			return TYPEFUNC_OTHER;
	}
	/* shouldn't get here, probably */
	return TYPEFUNC_OTHER;
}
예제 #2
0
bool isGreenplumDbHashable(Oid typid)
{
	/* we can hash all arrays */
	if (typeIsArrayType(typid))
		return true;
	/*
	 * if this type is a domain type, get its base type.
	 */
	if (get_typtype(typid) == 'd')
		typid = getBaseType(typid);
	
	switch(typid)
	{
		case INT2OID:		
		case INT4OID:		
		case INT8OID:		
		case FLOAT4OID:
		case FLOAT8OID:
		case NUMERICOID:
		case CHAROID:			
		case BPCHAROID: 
		case TEXTOID:	
		case VARCHAROID:
		case BYTEAOID:
		case NAMEOID:
		case OIDOID:
        case TIDOID:
		case REGPROCOID:		
		case REGPROCEDUREOID:		
		case REGOPEROID:		
		case REGOPERATOROID:		
		case REGCLASSOID:			
		case REGTYPEOID:		
		case TIMESTAMPOID:		
		case TIMESTAMPTZOID:	
		case DATEOID:			
		case TIMEOID:			
		case TIMETZOID: 
		case INTERVALOID:		
		case ABSTIMEOID:
		case RELTIMEOID:
		case TINTERVALOID:
		case INETOID:
		case CIDROID:
		case MACADDROID:
		case BITOID:
		case VARBITOID:
		case BOOLOID:			
		case ACLITEMOID:
		case ANYARRAYOID:	
		case INT2VECTOROID:
		case OIDVECTOROID:	
		case CASHOID: 
			return true;
		default:
			return false;
	}
}
예제 #3
0
/*
 * Convert a Python object to a PostgreSQL bool datum.	This can't go
 * through the generic conversion function, because Python attaches a
 * Boolean value to everything, more things than the PostgreSQL bool
 * type can parse.
 */
static Datum
PLyObject_ToBool(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
{
	Datum		rv;

	Assert(plrv != Py_None);
	rv = BoolGetDatum(PyObject_IsTrue(plrv));

	if (get_typtype(arg->typoid) == TYPTYPE_DOMAIN)
		domain_check(rv, false, arg->typoid, &arg->typfunc.fn_extra, arg->typfunc.fn_mcxt);

	return rv;
}
예제 #4
0
static Datum
PLySequence_ToArray(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
{
	ArrayType  *array;
	Datum		rv;
	int			i;
	Datum	   *elems;
	bool	   *nulls;
	int			len;
	int			lbs;

	Assert(plrv != Py_None);

	if (!PySequence_Check(plrv))
		PLy_elog(ERROR, "return value of function with array return type is not a Python sequence");

	len = PySequence_Length(plrv);
	elems = palloc(sizeof(*elems) * len);
	nulls = palloc(sizeof(*nulls) * len);

	for (i = 0; i < len; i++)
	{
		PyObject   *obj = PySequence_GetItem(plrv, i);

		if (obj == Py_None)
			nulls[i] = true;
		else
		{
			nulls[i] = false;
			elems[i] = arg->elm->func(arg->elm, -1, obj);
		}
		Py_XDECREF(obj);
	}

	lbs = 1;
	array = construct_md_array(elems, nulls, 1, &len, &lbs,
							   get_base_element_type(arg->typoid), arg->elm->typlen, arg->elm->typbyval, arg->elm->typalign);

	/*
	 * If the result type is a domain of array, the resulting array must be
	 * checked.
	 */
	rv = PointerGetDatum(array);
	if (get_typtype(arg->typoid) == TYPTYPE_DOMAIN)
		domain_check(rv, false, arg->typoid, &arg->typfunc.fn_extra, arg->typfunc.fn_mcxt);
	return rv;
}
예제 #5
0
/*
 * Convert a Python object to a PostgreSQL bytea datum.  This doesn't
 * go through the generic conversion function to circumvent problems
 * with embedded nulls.  And it's faster this way.
 */
static Datum
PLyObject_ToBytea(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
{
	PyObject   *volatile plrv_so = NULL;
	Datum		rv;

	Assert(plrv != Py_None);

	plrv_so = PyObject_Bytes(plrv);
	if (!plrv_so)
		PLy_elog(ERROR, "could not create bytes representation of Python object");

	PG_TRY();
	{
		char	   *plrv_sc = PyBytes_AsString(plrv_so);
		size_t		len = PyBytes_Size(plrv_so);
		size_t		size = len + VARHDRSZ;
		bytea	   *result = palloc(size);

		SET_VARSIZE(result, size);
		memcpy(VARDATA(result), plrv_sc, len);
		rv = PointerGetDatum(result);
	}
	PG_CATCH();
	{
		Py_XDECREF(plrv_so);
		PG_RE_THROW();
	}
	PG_END_TRY();

	Py_XDECREF(plrv_so);

	if (get_typtype(arg->typoid) == TYPTYPE_DOMAIN)
		domain_check(rv, false, arg->typoid, &arg->typfunc.fn_extra, arg->typfunc.fn_mcxt);

	return rv;
}
예제 #6
0
TupleCheckStatus
FilterInit(Filter *filter, TupleDesc desc, Oid collation)
{
	int				i;
	ParsedFunction	func;
	HeapTuple		ftup;
	HeapTuple		ltup;
	Form_pg_proc	pp;
	Form_pg_language	lp;
	TupleCheckStatus	status = NEED_COERCION_CHECK;

	if (filter->funcstr == NULL)
		return NO_COERCION;

	/* parse filter function */
	func = ParseFunction(filter->funcstr, true);

	filter->funcid = func.oid;
	filter->nargs = func.nargs;
	for (i = 0; i < filter->nargs; i++)
	{
		/* Check for polymorphic types and internal pseudo-type argument */
		if (IsPolymorphicType(func.argtypes[i]) ||
			func.argtypes[i] == INTERNALOID)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("filter function does not support a polymorphic function and having a internal pseudo-type argument function: %s",
							get_func_name(filter->funcid))));

		filter->argtypes[i] = func.argtypes[i];
	}

	ftup = SearchSysCache(PROCOID, ObjectIdGetDatum(filter->funcid), 0, 0, 0);
	pp = (Form_pg_proc) GETSTRUCT(ftup);

	if (pp->proretset)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("filter function must not return set")));

	/* Check data type of the function result value */
	if (pp->prorettype == desc->tdtypeid && pp->prorettype != RECORDOID)
		status = NO_COERCION;
	else if (pp->prorettype == RECORDOID)
	{
		TupleDesc	resultDesc = NULL;

		/* Check for OUT parameters defining a RECORD result */
		resultDesc = build_function_result_tupdesc_t(ftup);

		if (resultDesc)
		{
			if (tupledesc_match(desc, resultDesc))
				status = NO_COERCION;

			FreeTupleDesc(resultDesc);
		}
	}
	else if (get_typtype(pp->prorettype) != TYPTYPE_COMPOSITE)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function return data type and target table data type do not match")));

	/* Get default values */
#if PG_VERSION_NUM >= 80400
	filter->fn_ndargs = pp->pronargdefaults;
	if (filter->fn_ndargs > 0)
	{
		Datum		proargdefaults;
		bool		isnull;
		char	   *str;
		List	   *defaults;
		ListCell   *l;

		filter->defaultValues = palloc(sizeof(Datum) * filter->fn_ndargs);
		filter->defaultIsnull = palloc(sizeof(bool) * filter->fn_ndargs);

		proargdefaults = SysCacheGetAttr(PROCOID, ftup,
										 Anum_pg_proc_proargdefaults,
										 &isnull);
		Assert(!isnull);
		str = TextDatumGetCString(proargdefaults);
		defaults = (List *) stringToNode(str);
		Assert(IsA(defaults, List));
		pfree(str);

		filter->econtext = CreateStandaloneExprContext();
		i = 0;
		foreach(l, defaults)
		{
			Expr		   *expr = (Expr *) lfirst(l);
			ExprState	   *argstate;
			ExprDoneCond	thisArgIsDone;

			argstate = ExecInitExpr(expr, NULL);

			filter->defaultValues[i] = ExecEvalExpr(argstate,
													filter->econtext,
													&filter->defaultIsnull[i],
													&thisArgIsDone);

			if (thisArgIsDone != ExprSingleResult)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("functions and operators can take at most one set argument")));

			i++;
		}
예제 #7
0
Datum
plpgsql_validator(PG_FUNCTION_ARGS)
{
	Oid			funcoid = PG_GETARG_OID(0);
	HeapTuple	tuple;
	Form_pg_proc proc;
	char		functyptype;
	int			numargs;
	Oid		   *argtypes;
	char	  **argnames;
	char	   *argmodes;
	bool		istrigger = false;
	int			i;

	if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
		PG_RETURN_VOID();

	/* Get the new function's pg_proc entry */
	tuple = SearchSysCache(PROCOID,
						   ObjectIdGetDatum(funcoid),
						   0, 0, 0);
	if (!HeapTupleIsValid(tuple))
		elog(ERROR, "cache lookup failed for function %u", funcoid);
	proc = (Form_pg_proc) GETSTRUCT(tuple);

	functyptype = get_typtype(proc->prorettype);

	/* Disallow pseudotype result */
	/* except for TRIGGER, RECORD, VOID, or polymorphic */
	if (functyptype == TYPTYPE_PSEUDO)
	{
		/* we assume OPAQUE with no arguments means a trigger */
		if (proc->prorettype == TRIGGEROID ||
			(proc->prorettype == OPAQUEOID && proc->pronargs == 0))
			istrigger = true;
		else if (proc->prorettype != RECORDOID &&
				 proc->prorettype != VOIDOID &&
				 !IsPolymorphicType(proc->prorettype))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("PL/pgSQL functions cannot return type %s",
							format_type_be(proc->prorettype))));
	}

	/* Disallow pseudotypes in arguments (either IN or OUT) */
	/* except for polymorphic */
	numargs = get_func_arg_info(tuple,
								&argtypes, &argnames, &argmodes);
	for (i = 0; i < numargs; i++)
	{
		if (get_typtype(argtypes[i]) == TYPTYPE_PSEUDO)
		{
			if (!IsPolymorphicType(argtypes[i]))
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("PL/pgSQL functions cannot accept type %s",
								format_type_be(argtypes[i]))));
		}
	}

	/* Postpone body checks if !check_function_bodies */
	if (check_function_bodies)
	{
		FunctionCallInfoData fake_fcinfo;
		FmgrInfo	flinfo;
		TriggerData trigdata;
		int			rc;

		/*
		 * Connect to SPI manager (is this needed for compilation?)
		 */
		if ((rc = SPI_connect()) != SPI_OK_CONNECT)
			elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));

		/*
		 * Set up a fake fcinfo with just enough info to satisfy
		 * plpgsql_compile().
		 */
		MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo));
		MemSet(&flinfo, 0, sizeof(flinfo));
		fake_fcinfo.flinfo = &flinfo;
		flinfo.fn_oid = funcoid;
		flinfo.fn_mcxt = CurrentMemoryContext;
		if (istrigger)
		{
			MemSet(&trigdata, 0, sizeof(trigdata));
			trigdata.type = T_TriggerData;
			fake_fcinfo.context = (Node *) &trigdata;
		}

		/* Test-compile the function */
		plpgsql_compile(&fake_fcinfo, true);

		/*
		 * Disconnect from SPI manager
		 */
		if ((rc = SPI_finish()) != SPI_OK_FINISH)
			elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc));
	}

	ReleaseSysCache(tuple);

	PG_RETURN_VOID();
}
예제 #8
0
/*
 * Validator for SQL language functions
 *
 * Parse it here in order to be sure that it contains no syntax errors.
 */
Datum
fmgr_sql_validator(PG_FUNCTION_ARGS)
{
	Oid			funcoid = PG_GETARG_OID(0);
	HeapTuple	tuple;
	Form_pg_proc proc;
	List	   *querytree_list;
	bool		isnull;
	Datum		tmp;
	char	   *prosrc;
	ErrorContextCallback sqlerrcontext;
	bool		haspolyarg;
	int			i;

	tuple = SearchSysCache(PROCOID,
						   ObjectIdGetDatum(funcoid),
						   0, 0, 0);
	if (!HeapTupleIsValid(tuple))
		elog(ERROR, "cache lookup failed for function %u", funcoid);
	proc = (Form_pg_proc) GETSTRUCT(tuple);

	/* Disallow pseudotype result */
	/* except for RECORD, VOID, ANYARRAY, or ANYELEMENT */
	if (get_typtype(proc->prorettype) == 'p' &&
		proc->prorettype != RECORDOID &&
		proc->prorettype != VOIDOID &&
		proc->prorettype != ANYARRAYOID &&
		proc->prorettype != ANYELEMENTOID)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
				 errmsg("SQL functions cannot return type %s",
						format_type_be(proc->prorettype))));

	/* Disallow pseudotypes in arguments */
	/* except for ANYARRAY or ANYELEMENT */
	haspolyarg = false;
	for (i = 0; i < proc->pronargs; i++)
	{
		if (get_typtype(proc->proargtypes.values[i]) == 'p')
		{
			if (proc->proargtypes.values[i] == ANYARRAYOID ||
				proc->proargtypes.values[i] == ANYELEMENTOID)
				haspolyarg = true;
			else
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
					 errmsg("SQL functions cannot have arguments of type %s",
							format_type_be(proc->proargtypes.values[i]))));
		}
	}

	/* Postpone body checks if !check_function_bodies */
	if (check_function_bodies)
	{
		tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
		if (isnull)
			elog(ERROR, "null prosrc");

		prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp));

		/*
		 * Setup error traceback support for ereport().
		 */
		sqlerrcontext.callback = sql_function_parse_error_callback;
		sqlerrcontext.arg = tuple;
		sqlerrcontext.previous = error_context_stack;
		error_context_stack = &sqlerrcontext;

		/*
		 * We can't do full prechecking of the function definition if there
		 * are any polymorphic input types, because actual datatypes of
		 * expression results will be unresolvable.  The check will be done at
		 * runtime instead.
		 *
		 * We can run the text through the raw parser though; this will at
		 * least catch silly syntactic errors.
		 */
		if (!haspolyarg)
		{
			querytree_list = pg_parse_and_rewrite(prosrc,
												  proc->proargtypes.values,
												  proc->pronargs);
			(void) check_sql_fn_retval(funcoid, proc->prorettype,
									   querytree_list, NULL);
		}
		else
			querytree_list = pg_parse_query(prosrc);

		error_context_stack = sqlerrcontext.previous;
	}

	ReleaseSysCache(tuple);

	PG_RETURN_VOID();
}
예제 #9
0
static void
FunctionParserInit(FunctionParser *self, Checker *checker, const char *infile, TupleDesc desc, bool multi_process, Oid collation)
{
	int					i;
	ParsedFunction		function;
	int					nargs;
	Oid					funcid;
	HeapTuple			ftup;
	Form_pg_proc		pp;
	bool				tupledesc_matched = false;

	if (pg_strcasecmp(infile, "stdin") == 0)
		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						errmsg("cannot load from STDIN in the case of \"TYPE = FUNCTION\"")));

	if (checker->encoding != -1)
		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						errmsg("does not support parameter \"ENCODING\" in \"TYPE = FUNCTION\"")));

	function = ParseFunction(infile, false);

	funcid = function.oid;
	fmgr_info(funcid, &self->flinfo);

	if (!self->flinfo.fn_retset)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("function must return set")));

	ftup = SearchSysCache(PROCOID, ObjectIdGetDatum(funcid), 0, 0, 0);
	pp = (Form_pg_proc) GETSTRUCT(ftup);

	/* Check data type of the function result value */
	if (pp->prorettype == desc->tdtypeid && desc->tdtypeid != RECORDOID)
		tupledesc_matched = true;
	else if (pp->prorettype == RECORDOID)
	{
		TupleDesc	resultDesc = NULL;

		/* Check for OUT parameters defining a RECORD result */
		resultDesc = build_function_result_tupdesc_t(ftup);

		if (resultDesc)
		{
			tupledesc_match(desc, resultDesc);
			tupledesc_matched = true;
			FreeTupleDesc(resultDesc);
		}
	}
	else if (get_typtype(pp->prorettype) != TYPTYPE_COMPOSITE)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function return data type and target table data type do not match")));

	if (tupledesc_matched && checker->tchecker)
		checker->tchecker->status = NO_COERCION;

	/*
	 * assign arguments
	 */
	nargs = function.nargs;
	for (i = 0;
#if PG_VERSION_NUM >= 80400
		i < nargs - function.nvargs;
#else
		i < nargs;
#endif
		++i)
	{
		if (function.args[i] == NULL)
		{
			if (self->flinfo.fn_strict)
				ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					errmsg("function is strict, but argument %d is NULL", i)));
			self->fcinfo.argnull[i] = true;
		}
		else
		{
			Oid			typinput;
			Oid			typioparam;

			getTypeInputInfo(pp->proargtypes.values[i], &typinput, &typioparam);
			self->fcinfo.arg[i] = OidInputFunctionCall(typinput,
									(char *) function.args[i], typioparam, -1);
			self->fcinfo.argnull[i] = false;
			pfree(function.args[i]);
		}
	}

	/*
	 * assign variadic arguments
	 */
#if PG_VERSION_NUM >= 80400
	if (function.nvargs > 0)
	{
		int			nfixedarg;
		Oid			func;
		Oid			element_type;
		int16		elmlen;
		bool		elmbyval;
		char		elmalign;
		char		elmdelim;
		Oid			elmioparam;
		Datum	   *elems;
		bool	   *nulls;
		int			dims[1];
		int			lbs[1];
		ArrayType  *arry;

		nfixedarg = i;
		element_type = pp->provariadic;

		/*
		 * Get info about element type, including its input conversion proc
		 */
		get_type_io_data(element_type, IOFunc_input,
						 &elmlen, &elmbyval, &elmalign, &elmdelim,
						 &elmioparam, &func);

		elems = (Datum *) palloc(function.nvargs * sizeof(Datum));
		nulls = (bool *) palloc0(function.nvargs * sizeof(bool));
		for (i = 0; i < function.nvargs; i++)
		{
			if (function.args[nfixedarg + i] == NULL)
				nulls[i] = true;
			else
			{
				elems[i] = OidInputFunctionCall(func,
								(char *) function.args[nfixedarg + i], elmioparam, -1);
				pfree(function.args[nfixedarg + i]);
			}
		}

		dims[0] = function.nvargs;
		lbs[0] = 1;
		arry = construct_md_array(elems, nulls, 1, dims, lbs, element_type,
								  elmlen, elmbyval, elmalign);
		self->fcinfo.arg[nfixedarg] = PointerGetDatum(arry);
	}

	/*
	 * assign default arguments
	 */
	if (function.ndargs > 0)
	{
		Datum		proargdefaults;
		bool		isnull;
		char	   *str;
		List	   *defaults;
		int			ndelete;
		ListCell   *l;

		/* shouldn't happen, FuncnameGetCandidates messed up */
		if (function.ndargs > pp->pronargdefaults)
			elog(ERROR, "not enough default arguments");

		proargdefaults = SysCacheGetAttr(PROCOID, ftup,
										 Anum_pg_proc_proargdefaults,
										 &isnull);
		Assert(!isnull);
		str = TextDatumGetCString(proargdefaults);
		defaults = (List *) stringToNode(str);
		Assert(IsA(defaults, List));
		pfree(str);
		/* Delete any unused defaults from the returned list */
		ndelete = list_length(defaults) - function.ndargs;
		while (ndelete-- > 0)
			defaults = list_delete_first(defaults);

		self->arg_econtext = CreateStandaloneExprContext();
		foreach(l, defaults)
		{
			Expr	   *expr = (Expr *) lfirst(l);
			ExprState  *argstate;
			ExprDoneCond thisArgIsDone;

			/* probably shouldn't happen ... */
			if (nargs >= FUNC_MAX_ARGS)
				ereport(ERROR,
						(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
				 errmsg("cannot pass more than %d arguments to a function", FUNC_MAX_ARGS)));

			argstate = ExecInitExpr(expr, NULL);

			self->fcinfo.arg[nargs] = ExecEvalExpr(argstate,
												   self->arg_econtext,
												   &self->fcinfo.argnull[nargs],
												   &thisArgIsDone);

			if (thisArgIsDone != ExprSingleResult)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("functions and operators can take at most one set argument")));

			nargs++;
		}
예제 #10
0
파일: cdbhash.c 프로젝트: ahachete/gpdb
bool isGreenplumDbHashable(Oid typid)
{
	/* we can hash all arrays */
	if (typeIsArrayType(typid))
		return true;

	/* if this type is a domain type, get its base type */
	if (get_typtype(typid) == 'd')
		typid = getBaseType(typid);
	
	/* we can hash all enums */
	if (typeIsEnumType(typid))
		return true;

	/*
	 * NB: Every GPDB-hashable datatype must also be mergejoinable, i.e.
	 * must have a B-tree operator family. There is a sanity check for
	 * that in the opr_sanity_gp regression test. If you modify the list
	 * below, please also update the list in opr_sanity_gp!
	 */
	switch(typid)
	{
		case INT2OID:		
		case INT4OID:		
		case INT8OID:		
		case FLOAT4OID:
		case FLOAT8OID:
		case NUMERICOID:
		case CHAROID:			
		case BPCHAROID: 
		case TEXTOID:	
		case VARCHAROID:
		case BYTEAOID:
		case NAMEOID:
		case OIDOID:
        case TIDOID:
		case REGPROCOID:		
		case REGPROCEDUREOID:		
		case REGOPEROID:		
		case REGOPERATOROID:		
		case REGCLASSOID:			
		case REGTYPEOID:		
		case TIMESTAMPOID:		
		case TIMESTAMPTZOID:	
		case DATEOID:			
		case TIMEOID:			
		case TIMETZOID: 
		case INTERVALOID:		
		case ABSTIMEOID:
		case RELTIMEOID:
		case TINTERVALOID:
		case INETOID:
		case CIDROID:
		case MACADDROID:
		case BITOID:
		case VARBITOID:
		case BOOLOID:			
		case ANYARRAYOID:	
		case OIDVECTOROID:	
		case CASHOID: 
		case UUIDOID:
		case COMPLEXOID:
			return true;
		default:
			return false;
	}
}
예제 #11
0
파일: lsyscache.c 프로젝트: merlintang/sgb
/*
 * type_is_rowtype
 *
 *		Convenience function to determine whether a type OID represents
 *		a "rowtype" type --- either RECORD or a named composite type.
 */
bool
type_is_rowtype(Oid typid)
{
	return (typid == RECORDOID || get_typtype(typid) == 'c');
}