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

Reply via email to