Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add setting script_max_steps #15244

Merged
merged 1 commit into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,16 @@ impl Interpreter for ExecuteImmediateInterpreter {
#[async_backtrace::framed]
async fn execute2(&self) -> Result<PipelineBuildResult> {
let res: Result<_> = try {
let dialect = self.ctx.get_settings().get_sql_dialect()?;
let settings = self.ctx.get_settings();
let sql_dialect = settings.get_sql_dialect()?;
let tokens = tokenize_sql(&self.plan.script)?;
let mut ast = run_parser(&tokens, dialect, ParseMode::Template, false, script_block)?;
let mut ast = run_parser(
&tokens,
sql_dialect,
ParseMode::Template,
false,
script_block,
)?;

let mut src = vec![];
for declare in ast.declares {
Expand All @@ -100,7 +107,8 @@ impl Interpreter for ExecuteImmediateInterpreter {
ctx: self.ctx.clone(),
};
let mut executor = Executor::load(ast.span, client, compiled);
let result = executor.run(/* TODO(andylokandy) */ 1000).await?;
let script_max_steps = settings.get_script_max_steps()?;
let result = executor.run(script_max_steps as usize).await?;

match result {
Some(ReturnValue::Var(scalar)) => {
Expand Down
6 changes: 6 additions & 0 deletions src/query/settings/src/settings_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,12 @@ impl DefaultSettings {
desc: "The maximum waiting seconds in the queue. The default value is 0(no limit).",
mode: SettingMode::Both,
range: Some(SettingRange::Numeric(0..=u64::MAX)),
}),
("script_max_steps", DefaultSettingValue {
value: UserSettingValue::UInt64(10000),
desc: "The maximum steps allowed in a single execution of script.",
mode: SettingMode::Both,
range: Some(SettingRange::Numeric(0..=u64::MAX)),
})
]);

Expand Down
4 changes: 4 additions & 0 deletions src/query/settings/src/settings_getter_setter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,4 +627,8 @@ impl Settings {
pub fn get_statement_queued_timeout(&self) -> Result<u64> {
self.try_get_u64("statement_queued_timeout_in_seconds")
}

pub fn get_script_max_steps(&self) -> Result<u64> {
self.try_get_u64("script_max_steps")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,37 @@ END;
$$;
----

statement ok
set script_max_steps = 100;

query error exceeded the limit
EXECUTE IMMEDIATE $$
BEGIN
LET sum := 0;
WHILE sum < 100 DO
sum := sum +1;
END WHILE;
RETURN sum;
END;
$$;
----

statement ok
set script_max_steps = 1000;

query
EXECUTE IMMEDIATE $$
BEGIN
LET sum := 0;
WHILE sum < 100 DO
sum := sum +1;
END WHILE;
RETURN sum;
END;
$$;
----
100


statement ok
drop database test_procedure;
Loading