On 2024-05-20 05:02 +0200, Tom Lane wrote: > Erik Wienhold <e...@ewie.name> writes: > > On 2024-05-20 03:26 +0200, jian he wrote: > >> /* Check parameter number is in range */ > >> if (paramno <= 0 || paramno > MaxAllocSize / sizeof(Oid)) > >> ereport(ERROR, ... > > > Yes, it makes sense to show the upper bound. How about a hint such as > > "Valid parameters range from $%d to $%d."? > > I kind of feel like this upper bound is ridiculous. In what scenario > is parameter 250000000 not a mistake, if not indeed somebody trying > to break the system? > > The "Bind" protocol message only allows an int16 parameter count, > so rejecting parameter numbers above 32K would make sense to me.
Agree. I was already wondering upthread why someone would use that many parameters. Out of curiosity, I checked if there might be an even lower limit. And indeed, max_stack_depth puts a limit due to some recursive evaluation: ERROR: stack depth limit exceeded HINT: Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate. Attached is the stacktrace for EXECUTE on HEAD (I snipped most of the recursive frames). Running \bind, PREPARE, and EXECUTE with following number of parameters works as expected, although the number varies between releases which is not ideal IMO. The commands hit the stack depth limit for #Params+1. Version Command #Params ----------------- ------- ------- HEAD (18cbed13d5) \bind 4365 HEAD (18cbed13d5) PREPARE 8182 HEAD (18cbed13d5) EXECUTE 4363 16.2 \bind 3968 16.2 PREPARE 6889 16.2 EXECUTE 3966 Those are already pretty large numbers in my view (compared to the 100 parameters that we accept at most for functions). And I guess nobody complained about those limits yet, or they just increased max_stack_depth. The Python script to generate the test scripts: import sys n_params = 1 << 16 if len(sys.argv) > 1: n_params = min(n_params, int(sys.argv[1])) params = '+'.join(f'${i+1}::int' for i in range(n_params)) bind_vals = ' '.join('1' for _ in range(n_params)) exec_vals = ','.join('1' for _ in range(n_params)) print(fr"SELECT {params} \bind {bind_vals} \g") print(f"PREPARE p AS SELECT {params};") print(f"EXECUTE p ({exec_vals});") -- Erik
Breakpoint 1, errfinish (filename=0x6441fddaec2e "postgres.c", lineno=3535, funcname=0x6441fdef87a0 <__func__.14> "check_stack_depth") at elog.c:479 479 ErrorData *edata = &errordata[errordata_stack_depth]; #0 errfinish (filename=0x6441fddaec2e "postgres.c", lineno=3535, funcname=0x6441fdef87a0 <__func__.14> "check_stack_depth") at elog.c:479 #1 0x00006441fd898173 in check_stack_depth () at postgres.c:3535 #2 0x00006441fda5a9a2 in ExecInitExprRec (node=node@entry=0x6442373be5b0, state=state@entry=0x644236db7e90, resv=resv@entry=0x644236db7e98, resnull=resnull@entry=0x644236db7e95) at execExpr.c:899 #3 0x00006441fda5dc12 in ExecInitExpr (node=node@entry=0x6442373be5b0, parent=parent@entry=0x0) at execExpr.c:153 #4 0x00006441fdb52f58 in evaluate_expr (expr=0x6442373be5b0, result_type=result_type@entry=23, result_typmod=result_typmod@entry=-1, result_collation=result_collation@entry=0) at clauses.c:4987 #5 0x00006441fdb53181 in evaluate_function (func_tuple=0x71b8821811c0, funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args=0x6442373be520, funcvariadic=false, context=0x7ffd36b93cc0) at clauses.c:4503 #6 simplify_function (funcid=177, result_type=23, result_typmod=result_typmod@entry=-1, result_collid=0, input_collid=0, args_p=args_p@entry=0x7ffd36994940, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffd36b93cc0) at clauses.c:4092 #7 0x00006441fdb54624 in eval_const_expressions_mutator (node=<optimized out>, context=0x7ffd36b93cc0) at clauses.c:2639 #8 0x00006441fdacdf3a in expression_tree_mutator_impl (node=0x644236d87398, mutator=mutator@entry=0x6441fdb53a10 <eval_const_expressions_mutator>, context=context@entry=0x7ffd36b93cc0) at nodeFuncs.c:3554 #9 0x00006441fdb53781 in simplify_function (funcid=177, result_type=23, result_typmod=result_typmod@entry=-1, result_collid=0, input_collid=0, args_p=args_p@entry=0x7ffd36994b20, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffd36b93cc0) at clauses.c:4083 #10 0x00006441fdb54624 in eval_const_expressions_mutator (node=<optimized out>, context=0x7ffd36b93cc0) at clauses.c:2639 #11 0x00006441fdacdf3a in expression_tree_mutator_impl (node=0x644236d87308, mutator=mutator@entry=0x6441fdb53a10 <eval_const_expressions_mutator>, context=context@entry=0x7ffd36b93cc0) at nodeFuncs.c:3554 #12 0x00006441fdb53781 in simplify_function (funcid=177, result_type=23, result_typmod=result_typmod@entry=-1, result_collid=0, input_collid=0, args_p=args_p@entry=0x7ffd36994d00, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffd36b93cc0) at clauses.c:4083 #13 0x00006441fdb54624 in eval_const_expressions_mutator (node=<optimized out>, context=0x7ffd36b93cc0) at clauses.c:2639 #14 0x00006441fdacdf3a in expression_tree_mutator_impl (node=0x644236d87278, mutator=mutator@entry=0x6441fdb53a10 <eval_const_expressions_mutator>, context=context@entry=0x7ffd36b93cc0) at nodeFuncs.c:3554 #15 0x00006441fdb53781 in simplify_function (funcid=177, result_type=23, result_typmod=result_typmod@entry=-1, result_collid=0, input_collid=0, args_p=args_p@entry=0x7ffd36994ee0, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffd36b93cc0) at clauses.c:4083 [...snipped recursive frames...] #13084 0x00006441fdb54624 in eval_const_expressions_mutator (node=<optimized out>, context=0x7ffd36b93cc0) at clauses.c:2639 #13085 0x00006441fdacdf3a in expression_tree_mutator_impl (node=0x644236a70c20, mutator=mutator@entry=0x6441fdb53a10 <eval_const_expressions_mutator>, context=context@entry=0x7ffd36b93cc0) at nodeFuncs.c:3554 #13086 0x00006441fdb53781 in simplify_function (funcid=177, result_type=23, result_typmod=result_typmod@entry=-1, result_collid=0, input_collid=0, args_p=args_p@entry=0x7ffd36b93840, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffd36b93cc0) at clauses.c:4083 #13087 0x00006441fdb54624 in eval_const_expressions_mutator (node=<optimized out>, context=0x7ffd36b93cc0) at clauses.c:2639 #13088 0x00006441fdacdf3a in expression_tree_mutator_impl (node=0x644236a70b90, mutator=mutator@entry=0x6441fdb53a10 <eval_const_expressions_mutator>, context=context@entry=0x7ffd36b93cc0) at nodeFuncs.c:3554 #13089 0x00006441fdb53781 in simplify_function (funcid=177, result_type=23, result_typmod=result_typmod@entry=-1, result_collid=0, input_collid=0, args_p=args_p@entry=0x7ffd36b93a20, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffd36b93cc0) at clauses.c:4083 #13090 0x00006441fdb54624 in eval_const_expressions_mutator (node=<optimized out>, context=0x7ffd36b93cc0) at clauses.c:2639 #13091 0x00006441fdacdf3a in expression_tree_mutator_impl (node=0x644236a70b00, mutator=mutator@entry=0x6441fdb53a10 <eval_const_expressions_mutator>, context=context@entry=0x7ffd36b93cc0) at nodeFuncs.c:3554 #13092 0x00006441fdb53781 in simplify_function (funcid=177, result_type=23, result_typmod=result_typmod@entry=-1, result_collid=0, input_collid=0, args_p=args_p@entry=0x7ffd36b93c00, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffd36b93cc0) at clauses.c:4083 #13093 0x00006441fdb54624 in eval_const_expressions_mutator (node=<optimized out>, context=0x7ffd36b93cc0) at clauses.c:2639 #13094 0x00006441fdacd839 in expression_tree_mutator_impl (node=0x644236a70a70, mutator=0x6441fdb53a10 <eval_const_expressions_mutator>, context=0x7ffd36b93cc0) at nodeFuncs.c:3686 #13095 0x00006441fdacdf3a in expression_tree_mutator_impl (node=0x644236a70a28, mutator=0x6441fdb53a10 <eval_const_expressions_mutator>, context=0x7ffd36b93cc0) at nodeFuncs.c:3554 #13096 0x00006441fdb55006 in eval_const_expressions (root=root@entry=0x6442373bde80, node=<optimized out>) at clauses.c:2266 #13097 0x00006441fdb39981 in preprocess_expression (root=0x6442373bde80, expr=<optimized out>, kind=1) at planner.c:1169 #13098 0x00006441fdb41153 in subquery_planner (glob=glob@entry=0x6442373bdd78, parse=parse@entry=0x644236a707f8, parent_root=parent_root@entry=0x0, hasRecursion=hasRecursion@entry=false, tuple_fraction=tuple_fraction@entry=0, setops=setops@entry=0x0) at planner.c:835 #13099 0x00006441fdb41c97 in standard_planner (parse=0x644236a707f8, query_string=<optimized out>, cursorOptions=2048, boundParams=0x644236cded10) at planner.c:415 #13100 0x00006441fdc0961a in pg_plan_query (querytree=querytree@entry=0x644236a707f8, query_string=query_string@entry=0x6442369ae440 "PREPARE p AS SELECT $1::int+$2::int+$3::int+$4::int+$5::int+$6::int+$7::int+$8::int+$9::int+$10::int+$11::int+$12::int+$13::int+$14::int+$15::int+$16::int+$17::int+$18::int+$19::int+$20::int+$21::int+"..., cursorOptions=cursorOptions@entry=2048, boundParams=boundParams@entry=0x644236cded10) at postgres.c:904 #13101 0x00006441fdc09723 in pg_plan_queries (querytrees=querytrees@entry=0x644236a707b0, query_string=0x6442369ae440 "PREPARE p AS SELECT $1::int+$2::int+$3::int+$4::int+$5::int+$6::int+$7::int+$8::int+$9::int+$10::int+$11::int+$12::int+$13::int+$14::int+$15::int+$16::int+$17::int+$18::int+$19::int+$20::int+$21::int+"..., cursorOptions=2048, boundParams=boundParams@entry=0x644236cded10) at postgres.c:996 #13102 0x00006441fdd30523 in BuildCachedPlan (plansource=plansource@entry=0x644236894d58, qlist=0x644236a707b0, qlist@entry=0x0, boundParams=boundParams@entry=0x644236cded10, queryEnv=queryEnv@entry=0x0) at plancache.c:962 #13103 0x00006441fdd30faf in GetCachedPlan (plansource=0x644236894d58, boundParams=boundParams@entry=0x644236cded10, owner=owner@entry=0x0, queryEnv=queryEnv@entry=0x0) at plancache.c:1244 #13104 0x00006441fda1cbfd in ExecuteQuery (pstate=pstate@entry=0x6442368911b8, stmt=stmt@entry=0x644236a05570, intoClause=intoClause@entry=0x0, params=params@entry=0x0, dest=dest@entry=0x644236891130, qc=qc@entry=0x7ffd36b94050) at prepare.c:193 #13105 0x00006441fdc0ebb9 in standard_ProcessUtility (pstmt=0x6442369cd168, queryString=0x644236ac7f50 "EXECUTE p (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"..., readOnlyTree=<optimized out>, context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0x644236891130, qc=0x7ffd36b94050) at utility.c:750 #13106 0x00006441fdc0d07f in PortalRunUtility (portal=portal@entry=0x6442368e7478, pstmt=0x6442369cd168, isTopLevel=isTopLevel@entry=true, setHoldSnapshot=setHoldSnapshot@entry=true, dest=dest@entry=0x644236891130, qc=qc@entry=0x7ffd36b94050) at pquery.c:1158 #13107 0x00006441fdc0d427 in FillPortalStore (portal=portal@entry=0x6442368e7478, isTopLevel=isTopLevel@entry=true) at pquery.c:1031 #13108 0x00006441fdc0d71d in PortalRun (portal=portal@entry=0x6442368e7478, count=count@entry=9223372036854775807, isTopLevel=isTopLevel@entry=true, run_once=run_once@entry=true, dest=dest@entry=0x6442369cd270, altdest=altdest@entry=0x6442369cd270, qc=0x7ffd36b94260) at pquery.c:763 #13109 0x00006441fdc09acf in exec_simple_query (query_string=0x644236ac7f50 "EXECUTE p (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"...) at postgres.c:1274 #13110 0x00006441fdc0bdaa in PostgresMain (dbname=<optimized out>, username=<optimized out>) at postgres.c:4680 #13111 0x00006441fdc0628f in BackendMain (startup_data=<optimized out>, startup_data_len=<optimized out>) at backend_startup.c:105 #13112 0x00006441fdb78554 in postmaster_child_launch (child_type=child_type@entry=B_BACKEND, startup_data=startup_data@entry=0x7ffd36b946a0 "", startup_data_len=startup_data_len@entry=4, client_sock=client_sock@entry=0x7ffd36b946c0) at launch_backend.c:265 #13113 0x00006441fdb7bfd9 in BackendStartup (client_sock=0x7ffd36b946c0) at postmaster.c:3593 #13114 ServerLoop () at postmaster.c:1674 #13115 0x00006441fdb7dcdd in PostmasterMain (argc=argc@entry=4, argv=argv@entry=0x644236860e50) at postmaster.c:1372 #13116 0x00006441fd8bd713 in main (argc=4, argv=0x644236860e50) at main.c:197