diff --git a/contrib/babelfishpg_tsql/runtime/functions.c b/contrib/babelfishpg_tsql/runtime/functions.c index 61fb3e0019d..abc78726153 100644 --- a/contrib/babelfishpg_tsql/runtime/functions.c +++ b/contrib/babelfishpg_tsql/runtime/functions.c @@ -208,6 +208,7 @@ PG_FUNCTION_INFO_V1(datepart_internal_smallmoney); PG_FUNCTION_INFO_V1(replace_special_chars_fts); PG_FUNCTION_INFO_V1(isnumeric); PG_FUNCTION_INFO_V1(openxml_simple); +PG_FUNCTION_INFO_V1(is_table_type_oid); void *string_to_tsql_varchar(const char *input_str); void *get_servername_internal(void); @@ -6207,3 +6208,71 @@ bbf_xmlquery(PG_FUNCTION_ARGS) PG_RETURN_XML_P((xmltype *) cstring_to_text_with_len(buf.data, buf.len)); } + +Datum +is_table_type_oid(PG_FUNCTION_ARGS) +{ + Oid relid = PG_GETARG_OID(0); + HeapTuple classtup; + bool result = false; + + classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); + if (HeapTupleIsValid(classtup)) + { + Form_pg_class classform = (Form_pg_class) GETSTRUCT(classtup); + + if (classform->relkind == 'r') + { + HeapTuple typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(classform->reltype)); + if (HeapTupleIsValid(typtup)) + { + Form_pg_type typform = (Form_pg_type) GETSTRUCT(typtup); + + if (typform->typtype == 'c') + { + Relation depRel; + ScanKeyData key[3]; + SysScanDesc scan; + HeapTuple deptup; + + depRel = table_open(DependRelationId, AccessShareLock); + + ScanKeyInit(&key[0], + Anum_pg_depend_classid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationRelationId)); + ScanKeyInit(&key[1], + Anum_pg_depend_objid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(typform->typrelid)); + ScanKeyInit(&key[2], + Anum_pg_depend_objsubid, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(0)); + + scan = systable_beginscan(depRel, DependDependerIndexId, true, + NULL, 3, key); + + while (HeapTupleIsValid(deptup = systable_getnext(scan))) + { + Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(deptup); + + if (depform->deptype == 'i' && + depform->refobjid == typform->oid) + { + result = true; + break; + } + } + + systable_endscan(scan); + table_close(depRel, AccessShareLock); + } + ReleaseSysCache(typtup); + } + } + ReleaseSysCache(classtup); + } + + PG_RETURN_BOOL(result); +} diff --git a/contrib/babelfishpg_tsql/sql/sys_functions.sql b/contrib/babelfishpg_tsql/sql/sys_functions.sql index 3019427ae81..141d565e5d6 100644 --- a/contrib/babelfishpg_tsql/sql/sys_functions.sql +++ b/contrib/babelfishpg_tsql/sql/sys_functions.sql @@ -3977,20 +3977,9 @@ LANGUAGE C VOLATILE STRICT; * If a table is dependent upon it's row type with dependency type * as DEPENDENCY_INTERNAL (i) then it's a T-SQL table type. */ -CREATE OR REPLACE FUNCTION sys.is_table_type(object_id oid) RETURNS bool AS -$BODY$ -SELECT - EXISTS( - SELECT 1 - FROM pg_catalog.pg_type pt - INNER JOIN pg_catalog.pg_depend dep - ON pt.typrelid = dep.objid AND pt.oid = dep.refobjid - join sys.schemas sch on pt.typnamespace = sch.schema_id - JOIN pg_catalog.pg_class pc ON pc.oid = dep.objid - WHERE pt.typtype = 'c' AND dep.deptype = 'i' AND pt.typrelid = object_id AND pc.relkind = 'r' - AND dep.classid = 'pg_catalog.pg_class'::regclass AND dep.refclassid = 'pg_catalog.pg_type'::regclass); -$BODY$ -LANGUAGE SQL STABLE STRICT; +CREATE OR REPLACE FUNCTION sys.is_table_type(object_id oid) RETURNS bool +AS 'babelfishpg_tsql', 'is_table_type_oid' +LANGUAGE C STABLE STRICT; -- JSON Functions CREATE OR REPLACE FUNCTION sys.isjson(json_string text) diff --git a/contrib/babelfishpg_tsql/sql/sys_views.sql b/contrib/babelfishpg_tsql/sql/sys_views.sql index 8e13e48b298..2e3756f4a4a 100644 --- a/contrib/babelfishpg_tsql/sql/sys_views.sql +++ b/contrib/babelfishpg_tsql/sql/sys_views.sql @@ -8,9 +8,8 @@ create or replace view sys.table_types_internal as SELECT pt.typrelid FROM pg_catalog.pg_type pt INNER JOIN sys.schemas sch on pt.typnamespace = sch.schema_id - INNER JOIN pg_catalog.pg_depend dep ON pt.typrelid = dep.objid - INNER JOIN pg_catalog.pg_class pc ON pc.oid = dep.objid - WHERE pt.typtype = 'c' AND dep.deptype = 'i' AND pc.relkind = 'r'; + INNER JOIN pg_catalog.pg_class pc ON pc.oid = pt.typrelid + WHERE pt.typtype = 'c' AND pc.relkind = 'r' AND sys.is_table_type(pc.oid); create or replace view sys.tables as with tt_internal as MATERIALIZED diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--6.1.0--6.2.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--6.1.0--6.2.0.sql index bac6acc2315..24ca68acddb 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--6.1.0--6.2.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--6.1.0--6.2.0.sql @@ -208,6 +208,17 @@ CREATE OR REPLACE AGGREGATE sys.tsql_select_for_xml_text_agg( FINALFUNC = tsql_query_to_xml_text_ffunc ); +CREATE OR REPLACE FUNCTION sys.is_table_type(object_id oid) RETURNS bool +AS 'babelfishpg_tsql', 'is_table_type_oid' +LANGUAGE C STABLE STRICT; + +CREATE OR REPLACE VIEW sys.table_types_internal AS +SELECT pt.typrelid + FROM pg_catalog.pg_type pt + INNER JOIN sys.schemas sch on pt.typnamespace = sch.schema_id + INNER JOIN pg_catalog.pg_class pc ON pc.oid = pt.typrelid + WHERE pt.typtype = 'c' AND pc.relkind = 'r' AND sys.is_table_type(pc.oid); + -- Drops the temporary procedure used by the upgrade script. -- Please have this be one of the last statements executed in this upgrade script. DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar, varchar);