From 5d1135da917f39774df0ca496dd6a9612f544ada Mon Sep 17 00:00:00 2001 From: Shameem Ahmed Date: Tue, 10 Oct 2023 06:47:44 +0000 Subject: [PATCH] sp_describe_undeclared_parameters is slow Signed-off-by: Shameem Ahmed --- contrib/babelfishpg_tsql/src/procedures.c | 244 ++++++++++++---------- 1 file changed, 134 insertions(+), 110 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index 0295855fb3f..fc0efb47f6d 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -1288,141 +1288,165 @@ sp_describe_undeclared_parameters_internal(PG_FUNCTION_ARGS) * correct ordinal number in code. */ ", CAST( NULL AS sysname ) " /* AS "name" -- Need to get correct * parameter name in code. */ - ", CASE " - "WHEN T2.name COLLATE sys.database_default = \'bigint\' THEN 127 " - "WHEN T2.name COLLATE sys.database_default = \'binary\' THEN 173 " - "WHEN T2.name COLLATE sys.database_default = \'bit\' THEN 104 " - "WHEN T2.name COLLATE sys.database_default = \'char\' THEN 175 " - "WHEN T2.name COLLATE sys.database_default = \'date\' THEN 40 " - "WHEN T2.name COLLATE sys.database_default = \'datetime\' THEN 61 " - "WHEN T2.name COLLATE sys.database_default = \'datetime2\' THEN 42 " - "WHEN T2.name COLLATE sys.database_default = \'datetimeoffset\' THEN 43 " - "WHEN T2.name COLLATE sys.database_default = \'decimal\' THEN 106 " - "WHEN T2.name COLLATE sys.database_default = \'float\' THEN 62 " - "WHEN T2.name COLLATE sys.database_default = \'image\' THEN 34 " - "WHEN T2.name COLLATE sys.database_default = \'int\' THEN 56 " - "WHEN T2.name COLLATE sys.database_default = \'money\' THEN 60 " - "WHEN T2.name COLLATE sys.database_default = \'nchar\' THEN 239 " - "WHEN T2.name COLLATE sys.database_default = \'ntext\' THEN 99 " - "WHEN T2.name COLLATE sys.database_default = \'numeric\' THEN 108 " - "WHEN T2.name COLLATE sys.database_default = \'nvarchar\' THEN 231 " - "WHEN T2.name COLLATE sys.database_default = \'real\' THEN 59 " - "WHEN T2.name COLLATE sys.database_default = \'smalldatetime\' THEN 58 " - "WHEN T2.name COLLATE sys.database_default = \'smallint\' THEN 52 " - "WHEN T2.name COLLATE sys.database_default = \'smallmoney\' THEN 122 " - "WHEN T2.name COLLATE sys.database_default = \'text\' THEN 35 " - "WHEN T2.name COLLATE sys.database_default = \'time\' THEN 41 " - "WHEN T2.name COLLATE sys.database_default = \'tinyint\' THEN 48 " - "WHEN T2.name COLLATE sys.database_default = \'uniqueidentifier\' THEN 36 " - "WHEN T2.name COLLATE sys.database_default = \'varbinary\' THEN 165 " - "WHEN T2.name COLLATE sys.database_default = \'varchar\' THEN 167 " - "WHEN T2.name COLLATE sys.database_default = \'xml\' THEN 241 " - "ELSE C.system_type_id " + ", CASE T2.name COLLATE sys.database_default " + "WHEN \'bigint\' THEN 127 " + "WHEN \'binary\' THEN 173 " + "WHEN \'bit\' THEN 104 " + "WHEN \'char\' THEN 175 " + "WHEN \'date\' THEN 40 " + "WHEN \'datetime\' THEN 61 " + "WHEN \'datetime2\' THEN 42 " + "WHEN \'datetimeoffset\' THEN 43 " + "WHEN \'decimal\' THEN 106 " + "WHEN \'float\' THEN 62 " + "WHEN \'image\' THEN 34 " + "WHEN \'int\' THEN 56 " + "WHEN \'money\' THEN 60 " + "WHEN \'nchar\' THEN 239 " + "WHEN \'ntext\' THEN 99 " + "WHEN \'numeric\' THEN 108 " + "WHEN \'nvarchar\' THEN 231 " + "WHEN \'real\' THEN 59 " + "WHEN \'smalldatetime\' THEN 58 " + "WHEN \'smallint\' THEN 52 " + "WHEN \'smallmoney\' THEN 122 " + "WHEN \'text\' THEN 35 " + "WHEN \'time\' THEN 41 " + "WHEN \'tinyint\' THEN 48 " + "WHEN \'uniqueidentifier\' THEN 36 " + "WHEN \'varbinary\' THEN 165 " + "WHEN \'varchar\' THEN 167 " + "WHEN \'xml\' THEN 241 " + "ELSE " + "CASE " + "WHEN sys.translate_pg_type_to_tsql(a.atttypid) IS NOT NULL OR t.typbasetype = 0 THEN " + "CAST(a.atttypid AS int) " + "ELSE " + "CAST(t.typbasetype AS int) " + "END " "END " /* AS "suggested_system_type_id" */ - ", CASE " - "WHEN T2.name COLLATE sys.database_default = \'decimal\' THEN \'decimal(\' + CAST( C.precision AS sys.VARCHAR(10) ) + \',\' + CAST( C.scale AS sys.VARCHAR(10) ) + \')\' " - "WHEN T2.name COLLATE sys.database_default = \'numeric\' THEN \'numeric(\' + CAST( C.precision AS sys.VARCHAR(10) ) + \',\' + CAST( C.scale AS sys.VARCHAR(10) ) + \')\' " - "WHEN T2.name COLLATE sys.database_default = \'char\' THEN \'char(\' + CAST( C.max_length AS sys.VARCHAR(10) ) + \')\' " - "WHEN T2.name COLLATE sys.database_default = \'nchar\' THEN \'nchar(\' + CAST( C.max_length/2 AS sys.VARCHAR(10) ) + \')\' " - "WHEN T2.name COLLATE sys.database_default = \'binary\' THEN \'binary(\' + CAST( C.max_length AS sys.VARCHAR(10) ) + \')\' " - "WHEN T2.name COLLATE sys.database_default = \'datetime2\' THEN \'datetime2(\' + CAST( C.scale AS sys.VARCHAR(10) ) + \')\' " - "WHEN T2.name COLLATE sys.database_default = \'datetimeoffset\' THEN \'datetimeoffset(\' + CAST( C.scale AS sys.VARCHAR(10) ) + \')\' " - "WHEN T2.name COLLATE sys.database_default = \'time\' THEN \'time(\' + CAST( C.scale AS sys.VARCHAR(10) ) + \')\' " - "WHEN T2.name COLLATE sys.database_default = \'varchar\' THEN " - "CASE WHEN C.max_length = -1 THEN \'varchar(max)\' " - "ELSE \'varchar(\' + CAST( C.max_length AS sys.VARCHAR(10) ) + \')\' " + ", CASE T2.name COLLATE sys.database_default " + "WHEN \'decimal\' THEN \'decimal(\' + CAST( T2.precision AS sys.VARCHAR(10) ) + \',\' + CAST( T2.scale AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'numeric\' THEN \'numeric(\' + CAST( T2.precision AS sys.VARCHAR(10) ) + \',\' + CAST( T2.scale AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'char\' THEN \'char(\' + CAST( T2.max_length AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'nchar\' THEN \'nchar(\' + CAST( T2.max_length/2 AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'binary\' THEN \'binary(\' + CAST( T2.max_length AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'datetime2\' THEN \'datetime2(\' + CAST( T2.scale AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'datetimeoffset\' THEN \'datetimeoffset(\' + CAST( T2.scale AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'time\' THEN \'time(\' + CAST( T2.scale AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'varchar\' THEN " + "CASE WHEN T2.max_length = -1 THEN \'varchar(max)\' " + "ELSE \'varchar(\' + CAST( T2.max_length AS sys.VARCHAR(10) ) + \')\' " "END " - "WHEN T2.name COLLATE sys.database_default = \'nvarchar\' THEN " - "CASE WHEN C.max_length = -1 THEN \'nvarchar(max)\' " - "ELSE \'nvarchar(\' + CAST( C.max_length/2 AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'nvarchar\' THEN " + "CASE WHEN T2.max_length = -1 THEN \'nvarchar(max)\' " + "ELSE \'nvarchar(\' + CAST( T2.max_length/2 AS sys.VARCHAR(10) ) + \')\' " "END " - "WHEN T2.name COLLATE sys.database_default = \'varbinary\' THEN " - "CASE WHEN C.max_length = -1 THEN \'varbinary(max)\' " - "ELSE \'varbinary(\' + CAST( C.max_length AS sys.VARCHAR(10) ) + \')\' " + "WHEN \'varbinary\' THEN " + "CASE WHEN T2.max_length = -1 THEN \'varbinary(max)\' " + "ELSE \'varbinary(\' + CAST( T2.max_length AS sys.VARCHAR(10) ) + \')\' " "END " "ELSE T2.name " "END " /* AS "suggested_system_type_name" */ - ", CASE " - "WHEN T2.name COLLATE sys.database_default IN (\'image\', \'ntext\',\'text\') THEN -1 " - "ELSE C.max_length " + ", CASE T2.name COLLATE sys.database_default " + "WHEN \'image\' THEN -1 " + "WHEN \'ntext\' THEN -1 " + "WHEN \'text\' THEN -1 " + "ELSE T2.max_length " "END " /* AS "suggested_max_length" */ - ", C.precision " /* AS "suggested_precision" */ - ", C.scale " /* AS "suggested_scale" */ - ", CASE WHEN T.user_type_id = T.system_type_id THEN CAST( NULL AS INT ) ELSE T.user_type_id END " /* AS + ", T2.precision " /* AS "suggested_precision" */ + ", T2.scale " /* AS "suggested_scale" */ + ", CASE WHEN T2.user_type_id = T2.system_type_id THEN CAST( NULL AS INT ) ELSE T2.user_type_id END " /* AS * "suggested_user_type_id" */ - ", CASE WHEN T.user_type_id = T.system_type_id THEN CAST( NULL AS sysname) ELSE DB_NAME() END " /* AS + ", CASE WHEN T2.user_type_id = T2.system_type_id THEN CAST( NULL AS sysname) ELSE DB_NAME() END " /* AS * "suggested_user_type_database" */ - ", CASE WHEN T.user_type_id = T.system_type_id THEN CAST( NULL AS sysname) ELSE SCHEMA_NAME( T.schema_id ) END " /* AS + ", CASE WHEN T2.user_type_id = T2.system_type_id THEN CAST( NULL AS sysname) ELSE SCHEMA_NAME( T2.schema_id ) END " /* AS * "suggested_user_type_schema" */ - ", CASE WHEN T.user_type_id = T.system_type_id THEN CAST( NULL AS sysname) ELSE T.name END " /* AS + ", CASE WHEN T2.user_type_id = T2.system_type_id THEN CAST( NULL AS sysname) ELSE T2.name END " /* AS * "suggested_user_type_name" */ ", CAST( NULL AS NVARCHAR(4000) ) " /* AS * "suggested_assembly_qualified_type_name" */ - ", CASE " - "WHEN C.xml_collection_id = 0 THEN CAST( NULL AS INT ) " - "ELSE C.xml_collection_id " - "END " /* AS "suggested_xml_collection_id" */ + ", CAST( NULL AS INT ) " /* AS "suggested_xml_collection_id" */ ", CAST( NULL AS sysname ) " /* AS * "suggested_xml_collection_database" */ ", CAST( NULL AS sysname ) " /* AS * "suggested_xml_collection_schema" */ ", CAST( NULL AS sysname ) " /* AS "suggested_xml_collection_name" */ - ", C.is_xml_document " /* AS "suggested_is_xml_document" */ + ", CAST(0 AS sys.bit) " /* AS "suggested_is_xml_document" */ ", CAST( 0 AS BIT ) " /* AS "suggested_is_case_sensitive" */ ", CAST( 0 AS BIT ) " /* AS "suggested_is_fixed_length_clr_type" */ ", CAST( 1 AS BIT ) " /* AS "suggested_is_input" */ ", CAST( 0 AS BIT ) " /* AS "suggested_is_output" */ ", CAST( NULL AS sysname ) " /* AS "formal_parameter_name" */ - ", CASE " - "WHEN T2.name COLLATE sys.database_default IN (\'tinyint\', \'smallint\', \'int\', \'bigint\') THEN 38 " - "WHEN T2.name COLLATE sys.database_default IN (\'float\', \'real\') THEN 109 " - "WHEN T2.name COLLATE sys.database_default IN (\'smallmoney\', \'money\') THEN 110 " - "WHEN T2.name COLLATE sys.database_default IN (\'smalldatetime\', \'datetime\') THEN 111 " - "WHEN T2.name COLLATE sys.database_default = \'binary\' THEN 173 " - "WHEN T2.name COLLATE sys.database_default = \'bit\' THEN 104 " - "WHEN T2.name COLLATE sys.database_default = \'char\' THEN 175 " - "WHEN T2.name COLLATE sys.database_default = \'date\' THEN 40 " - "WHEN T2.name COLLATE sys.database_default = \'datetime2\' THEN 42 " - "WHEN T2.name COLLATE sys.database_default = \'datetimeoffset\' THEN 43 " - "WHEN T2.name COLLATE sys.database_default = \'decimal\' THEN 106 " - "WHEN T2.name COLLATE sys.database_default = \'image\' THEN 34 " - "WHEN T2.name COLLATE sys.database_default = \'nchar\' THEN 239 " - "WHEN T2.name COLLATE sys.database_default = \'ntext\' THEN 99 " - "WHEN T2.name COLLATE sys.database_default = \'numeric\' THEN 108 " - "WHEN T2.name COLLATE sys.database_default = \'nvarchar\' THEN 231 " - "WHEN T2.name COLLATE sys.database_default = \'text\' THEN 35 " - "WHEN T2.name COLLATE sys.database_default = \'time\' THEN 41 " - "WHEN T2.name COLLATE sys.database_default = \'uniqueidentifier\' THEN 36 " - "WHEN T2.name COLLATE sys.database_default= \'varbinary\' THEN 165 " - "WHEN T2.name COLLATE sys.database_default = \'varchar\' THEN 167 " - "WHEN T2.name COLLATE sys.database_default = \'xml\' THEN 241 " - "ELSE C.system_type_id " + ", CASE T2.name COLLATE sys.database_default " + "WHEN \'tinyint\' THEN 38 " + "WHEN \'smallint\' THEN 38 " + "WHEN \'int\' THEN 38 " + "WHEN \'bigint\' THEN 38 " + "WHEN \'float\' THEN 109 " + "WHEN \'real\' THEN 109 " + "WHEN \'smallmoney\' THEN 110 " + "WHEN \'money\' THEN 110 " + "WHEN \'smalldatetime\' THEN 111 " + "WHEN \'datetime\' THEN 111 " + "WHEN \'binary\' THEN 173 " + "WHEN \'bit\' THEN 104 " + "WHEN \'char\' THEN 175 " + "WHEN \'date\' THEN 40 " + "WHEN \'datetime2\' THEN 42 " + "WHEN \'datetimeoffset\' THEN 43 " + "WHEN \'decimal\' THEN 106 " + "WHEN \'image\' THEN 34 " + "WHEN \'nchar\' THEN 239 " + "WHEN \'ntext\' THEN 99 " + "WHEN \'numeric\' THEN 108 " + "WHEN \'nvarchar\' THEN 231 " + "WHEN \'text\' THEN 35 " + "WHEN \'time\' THEN 41 " + "WHEN \'uniqueidentifier\' THEN 36 " + "WHEN \'varbinary\' THEN 165 " + "WHEN \'varchar\' THEN 167 " + "WHEN \'xml\' THEN 241 " + "ELSE " + "CASE " + "WHEN sys.translate_pg_type_to_tsql(a.atttypid) IS NOT NULL OR t.typbasetype = 0 THEN " + "CAST(a.atttypid AS int) " + "ELSE " + "CAST(t.typbasetype AS int) " + "END " "END " /* AS "suggested_tds_type_id" */ - ", CASE " - "WHEN T2.name COLLATE sys.database_default = \'nvarchar\' AND C.max_length = -1 THEN 65535 " - "WHEN T2.name COLLATE sys.database_default = \'varbinary\' AND C.max_length = -1 THEN 65535 " - "WHEN T2.name COLLATE sys.database_default = \'varchar\' AND C.max_length = -1 THEN 65535 " - "WHEN T2.name COLLATE sys.database_default IN (\'decimal\', \'numeric\') THEN 17 " - "WHEN T2.name COLLATE sys.database_default = \'xml\' THEN 8100 " - "WHEN T2.name COLLATE sys.database_default in (\'image\', \'text\') THEN 2147483647 " - "WHEN T2.name COLLATE sys.database_default = \'ntext\' THEN 2147483646 " - "ELSE CAST( C.max_length AS INT ) " + ", CASE T2.name COLLATE sys.database_default " + "WHEN \'nvarchar\' THEN " + "CASE WHEN T2.max_length = -1 THEN 65535 " + "ELSE T2.max_length " + "END " + "WHEN \'varbinary\' THEN " + "CASE WHEN T2.max_length = -1 THEN 65535 " + "ELSE T2.max_length " + "END " + "WHEN \'varchar\' THEN " + "CASE WHEN T2.max_length = -1 THEN 65535 " + "ELSE T2.max_length " + "END " + "WHEN \'decimal\' THEN 17 " + "WHEN \'numeric\' THEN 17 " + "WHEN \'xml\' THEN 8100 " + "WHEN \'image\' THEN 2147483647 " + "WHEN \'text\' THEN 2147483647 " + "WHEN \'ntext\' THEN 2147483646 " + "ELSE CAST( T2.max_length AS INT ) " "END " /* AS "suggested_tds_length" */ - "FROM sys.objects O, sys.columns C, sys.types T, sys.types T2 " - "WHERE O.object_id = C.object_id " - "AND C.user_type_id = T.user_type_id " - "AND C.name = \'%s\' COLLATE sys.database_default " /* -- INPUT column name */ - "AND T.system_type_id = T2.user_type_id " /* -- To get system dt - * name. */ - "AND O.name = \'%s\' COLLATE sys.database_default " /* -- INPUT table name */ - "AND O.schema_id = %d " /* -- INPUT schema Oid */ - "AND O.type = \'U\'"; /* -- User tables only for the time being */ - - char *query = psprintf(tempq, - undeclaredparams->targetcolnames[undeclaredparams->paramindexes[call_cntr]], - undeclaredparams->tablename, - undeclaredparams->schemaoid); - + "FROM sys.types T2, pg_class c, pg_attribute a, pg_type t, pg_namespace base " + "WHERE c.oid = a.attrelid " + "AND a.atttypid = t.oid " + "AND a.attname = \'%s\' COLLATE sys.database_default " /* -- INPUT column name -- */ + " AND c.relname = \'%s\' COLLATE sys.database_default " /* -- INPUT table name -- */ + "AND base.oid = %d "; /* -- INPUT schema Oid -- */ + + char *query = psprintf(tempq, + undeclaredparams->targetcolnames[undeclaredparams->paramindexes[call_cntr]], + undeclaredparams->tablename, + undeclaredparams->schemaoid); int rc = SPI_execute(query, true, 1); if (rc != SPI_OK_SELECT)