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

sql: mark functions as Immutable/Stable/Volatile #48491

Merged
merged 1 commit into from
May 7, 2020

Conversation

otan
Copy link
Contributor

@otan otan commented May 6, 2020

This commit adds the "Volatile" argument to all function properties,
replacing the "Impure" definition. I've replaced all "Impure" checks
with "!= VolatilityImmutable` to give equivalent functionality for now -
we can enhance the folding and the like in a later commit. The planner
tweaks can come from someone more familiar with it :).

Also updated the pg_proc table, which should be the only visible user
change.

Refs #26582.

Release note (sql change): Populated the pg_proc table's provolatile
field based on the internal builtin volatility definition. This value
used to always be NULL.

@otan otan requested a review from maddyblue May 6, 2020 14:56
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@otan otan requested a review from RaduBerinde May 6, 2020 14:57
@otan
Copy link
Contributor Author

otan commented May 6, 2020

(let me know if this should be "touches" instead)

@otan otan force-pushed the add_volatility branch 2 times, most recently from ba3a3ab to 198edc0 Compare May 6, 2020 15:02
@blathers-crl
Copy link

blathers-crl bot commented May 6, 2020

❌ The GitHub CI (Cockroach) build has failed on 198edc0f.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

@otan otan changed the title sql: mark functions as Immutable/Stable/Volatile as just Pure/Impure sql: mark functions as Immutable/Stable/Volatile from Pure/Impure May 6, 2020
@otan otan changed the title sql: mark functions as Immutable/Stable/Volatile from Pure/Impure sql: mark functions as Immutable/Stable/Volatile May 6, 2020
pkg/sql/pg_catalog.go Outdated Show resolved Hide resolved
pkg/sql/sem/tree/function_definition.go Outdated Show resolved Hide resolved
pkg/sql/sem/tree/function_definition.go Outdated Show resolved Hide resolved
@blathers-crl
Copy link

blathers-crl bot commented May 6, 2020

❌ The GitHub CI (Cockroach) build has failed on 695575e2.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

Copy link
Contributor

@maddyblue maddyblue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like a test added that asserts that all for all builtins with fnProps defined, the volatility is not the zero value.

@otan
Copy link
Contributor Author

otan commented May 6, 2020

I've made the builtins be defined as immutable (like we do today as impure=false) if not filled in on init time. Do you want that to be different?

@otan
Copy link
Contributor Author

otan commented May 6, 2020

(would you rather make fnProps fill in the volatility by default, and then anyone who defined FunctionProperties manually must define their own?)

for _, name := range AllBuiltinNames {
def := builtins[name]
if def.props.Volatility == 0 {
def.props.Volatility = tree.VolatilityImmutable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add something like: TODO: instead of the default being immutable (which could be a problem if a new function forgets to set its volatility if not immutable), explicitly define volatility of all functions and add a test that asserts it is never the zero value.

@blathers-crl
Copy link

blathers-crl bot commented May 6, 2020

❌ The GitHub CI (Cockroach) build has failed on 3826bba5.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

@RaduBerinde
Copy link
Member

I've made the builtins be defined as immutable (like we do today as impure=false) if not filled in on init time. Do you want that to be different?

Unfortunately, what we currently do is the worst thing we can do.. If someone adds a builtin without thinking about volatility or even knowing much about it, we should be conservative with the default. I do prefer that we require it explicitly everywhere, and maybe just document that "if in doubt, use volatile". I realize this is a very tedious change :/

Note that because of this unsafe default, we can't completely trust this flag today and the optimizer has its own "whitelist" of functions here: https://github.com/cockroachdb/cockroach/blob/2f08e8ea772d4619b66182020cb9453ad341fcbb/pkg/sql/opt/norm/fold_constants.go#L418
This would need to be resolved before closing the issue.

@otan
Copy link
Contributor Author

otan commented May 6, 2020

alright, we can make that change separately. I'll put this in as a first step.

@blathers-crl
Copy link

blathers-crl bot commented May 6, 2020

❌ The GitHub CI (Cockroach) build has failed on 6eeb0c53.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

@blathers-crl
Copy link

blathers-crl bot commented May 6, 2020

❌ The GitHub CI (Cockroach) build has failed on b2b926eb.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

This commit adds the "Volatile" argument to all function properties,
replacing the "Impure" definition. I've replaced all "Impure" checks
with "!= VolatilityImmutable` to give equivalent functionality for now -
we can enhance the folding and the like in a later commit. The planner
tweaks can come from someone more familiar with it :).

Also updated the pg_proc table, which should be the only visible user
change.

Release note (sql change): Populated the `pg_proc` table's `provolatile`
field based on the internal builtin volatility definition. This value
used to always be NULL.
@maddyblue
Copy link
Contributor

Is this ready to go now?

@otan
Copy link
Contributor Author

otan commented May 7, 2020

yep!

i'm planning on auditing everything for my flex friday, and doing the overload approach (unless you had something in mind). may be some more refactors over the same file, but whatever :P

bors r=mjibson

@maddyblue
Copy link
Contributor

Thanks, that sounds great.

Copy link
Member

@RaduBerinde RaduBerinde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argh..... I had some comments but apparently never hit Publish.. sorry about that. Can be addressed in a follow-up PR

Nice, thanks for working on this! CC @rytaft @andy-kimball

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @mjibson, @otan, and @RaduBerinde)


pkg/sql/sem/tree/function_definition.go, line 43 at r1 (raw file):

type Volatility int

const (

We need to document these as clearly as possible because this will be consulted any time someone adds or messes with a builtin, and it will be used when figuring out the correct logic in the optimizer. Better to be extra verbose - we should mention exactly what we can do with some examples. A while back I had thought of what semantics we would want for this property on the optimizer side, I wrote this comment: https://github.com/RaduBerinde/cockroach/blob/c11ad89fe595f9d378e234691bbd1f7d42eab488/pkg/sql/opt/props/volatility.go

We can lift some descriptions / comments from there. We should consider separating "volatile" from "mutation" (or "side-effecting") at the function level.


pkg/sql/sem/tree/function_definition.go, line 45 at r1 (raw file):

const (
	// VolatilityImmutable indicates the builtin result never changes for a
	// given input.

It does not depend on configuration settings, and does not modify the database, the transaction state, or any other state. Immutable functions can always be constant-folded (even in cached plans).


pkg/sql/sem/tree/function_definition.go, line 48 at r1 (raw file):

	VolatilityImmutable Volatility = iota
	// VolatilityStable indicates the builtin result never changes during
	// a given scan.

"during a given scan" is not very helpful. Maybe change to "the function cannot modify the database or the transaction state and is guaranteed to return the same results given the same arguments whenever it is evaluated within the same statement."


pkg/sql/sem/tree/function_definition.go, line 50 at r1 (raw file):

	// a given scan.
	VolatilityStable
	// VolatilityVolatile indicates the builtin result can change even

mention "or that it has side effects". I would remove the "impure" thing because it doesn't help here without a proper definition; we can add some examples of different things the function can do.


pkg/sql/sqlbase/table.go, line 34 at r2 (raw file):

// type and contains no variable expressions. It returns the type-checked and
// constant-folded expression.
func SanitizeVarFreeExpr(

[nit] I would break this out into SanitizeVarFreeExpr and SanitizeImmutableExpr. They can call out to the same unexported function (maybe passing the flags directly)

@craig
Copy link
Contributor

craig bot commented May 7, 2020

Build succeeded

@craig craig bot merged commit aa07ae0 into cockroachdb:master May 7, 2020
// given input.
VolatilityImmutable Volatility = 'i'
// VolatilityStable indicates the builtin result never changes during
// a given scan.
Copy link
Contributor

@andy-kimball andy-kimball May 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "given scan" part confuses me. I was expecting something like:

Immutable: never changes for a given input, even across multiple executions of a statement
Stable: never changes for a given input when invoked multiple times in a single statement, but may change across multiple executions of a statement
Volatile: may change when invoked multiple times in a single statement

Examples of each case would be helpful as well, to give people a quick intuition:

Immutable: length(...)
Stable: now()
Volatile: random()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix this up tomorrow! I have 1000 functions to audit :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants