diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index c61f31c6ac8..deb08ba0181 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -4314,9 +4314,24 @@ fetch_function_defaults(HeapTuple func_tuple) List *defaults; Datum proargdefaults; char *str; + bool isnull; + + /* The error cases here shouldn't happen, but check anyway */ + proargdefaults = SysCacheGetAttr(PROCOID, func_tuple, + Anum_pg_proc_proargdefaults, + &isnull); + if (isnull) + { + /* This error msg is not expected in Tsql for 2 reasons + 1. Procedure call will throw a specific error msg later + 2. Func call even without defining default value, it + won't error out, it'll use NULL instead */ + if (sql_dialect == SQL_DIALECT_TSQL) + return NIL; + + elog(ERROR, "not enough default arguments"); + } - proargdefaults = SysCacheGetAttrNotNull(PROCOID, func_tuple, - Anum_pg_proc_proargdefaults); str = TextDatumGetCString(proargdefaults); defaults = castNode(List, stringToNode(str)); pfree(str); diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 9f03bc7fa51..39a62e0b75b 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -3204,13 +3204,23 @@ transformCallStmt(ParseState *pstate, CallStmt *stmt) targs = NIL; foreach(lc, stmt->funccall->args) { - if (sql_dialect == SQL_DIALECT_TSQL && nodeTag((Node*)lfirst(lc)) == T_SetToDefault) + if (sql_dialect == SQL_DIALECT_TSQL && + (nodeTag((Node*)lfirst(lc)) == T_SetToDefault)) { // For Tsql Default in function call, we set it to UNKNOWN in parser stage // In analyzer it'll use other types to detect the right func candidate ((SetToDefault *)lfirst(lc))->typeId = UNKNOWNOID; targs = lappend(targs, (Node *) lfirst(lc)); } + else if (sql_dialect == SQL_DIALECT_TSQL && + nodeTag((Node*)lfirst(lc)) == T_NamedArgExpr && + nodeTag(((NamedArgExpr*)lfirst(lc))->arg) == T_SetToDefault) + { + // For Tsql Default in function call, we set it to UNKNOWN in parser stage + // In analyzer it'll use other types to detect the right func candidate + ((SetToDefault *)((NamedArgExpr*)lfirst(lc))->arg)->typeId = UNKNOWNOID; + targs = lappend(targs, (Node *) lfirst(lc)); + } else { targs = lappend(targs, transformExpr(pstate,