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

Various fixes found with sqlite fuzzer #1021

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open

Various fixes found with sqlite fuzzer #1021

wants to merge 24 commits into from

Conversation

jussisaurio
Copy link
Collaborator

@jussisaurio jussisaurio commented Feb 16, 2025

Discovering tons of shit with @sivukhin 's sqlite fuzzer

NOTE: this is an exploration PR and I will probably cherry-pick smaller PRs out of this. Mainly sqlite's affinity rules are giving tons of headaches since we're not implementing it properly right now.

PRs extracted so far:

#1023
#1024
#1025
#1031


Adds missing support:

  • Support all the same literals in WHERE clause position as in SELECT position
  • Support CAST in WHERE clause position
  • Support FunctionCall in WHERE clause position
  • Support Column in WHERE clause position
  • Support Rowid in WHERE clause position
  • Support CASE in WHERE clause position
  • Support LIKE in SELECT position
  • Support Unary expressions in WHERE clause position
  • Support rest of the Binary expressions in WHERE clause position
  • Support TEXT in remainder operations

Fixes:

  • Fix concat losing decimal precision of floats in text representation
  • Fix remainder panic on zero right-hand-side
  • Fix wrong text->numeric coercion in NOT context
  • Fix incorrect text->numeric coercion in logical OR
  • Fix equality comparisons for OwnedValue
  • Fix incorrectly always returning False for text in exec_if()
  • Fix never evaluating constant conditions at all
  • Fix cast_text_as_real() not allowing partial parse of exactly 1 char
  • Fix incorrect text->numeric coercion in CAST
  • Fix incorrect implementation of cast_text_to_numerical()
  • Remove incorrect constant folding optimization for NULL

Testing utils:

  • Enhance sqlite fuzzer to mostly be able to work with the same set of possible expressions in both SELECT and WHERE clause position

@jussisaurio jussisaurio force-pushed the expr-fixes branch 3 times, most recently from c7949a6 to 22c7286 Compare February 16, 2025 10:04
@jussisaurio jussisaurio force-pushed the expr-fixes branch 2 times, most recently from c644708 to 5a70745 Compare February 16, 2025 17:19
@jussisaurio jussisaurio changed the title Expr fixes Various fixes found with sqlite fuzzer Feb 16, 2025
@jussisaurio jussisaurio force-pushed the expr-fixes branch 2 times, most recently from a6a92d6 to cfff690 Compare February 16, 2025 18:18
jussisaurio added a commit that referenced this pull request Feb 17, 2025
…i Saurio

This PR is sourced from the fuzzing exploration PR in
#1021
**Adds missing support:**
Support all the same literals in WHERE clause position as in SELECT
position
Support CAST in WHERE clause position
Support FunctionCall in WHERE clause position
Support Column in WHERE clause position
Support Rowid in WHERE clause position
Support CASE in WHERE clause position
Support LIKE in SELECT position
Support Unary expressions in WHERE clause position
Support rest of the Binary expressions in WHERE clause position
Support TEXT in remainder operations
**Fix:**
Remove incorrect constant folding optimization for NULL
**Testing utils:**
Enhance sqlite fuzzer to mostly be able to work with the same set of
possible expressions in both SELECT and WHERE clause position

Closes #1024
penberg added a commit that referenced this pull request Feb 18, 2025
…rom Jussi Saurio

This PR is extracted from the sqlite fuzzing exploration effort in
#1021
---
We were not evaluating constant conditions (e.g '1 IS NULL') when there
were no tables referenced in the query, because our WHERE term
evaluation was based on "during which loop" to evaluate them. However,
when there are no tables, there are no loops, so they were never
evaluated.

Closes #1023
@@ -1023,64 +1057,71 @@ pub fn exec_boolean_not(mut reg: &OwnedValue) -> OwnedValue {
OwnedValue::Null => OwnedValue::Null,
OwnedValue::Integer(i) => OwnedValue::Integer((*i == 0) as i64),
OwnedValue::Float(f) => OwnedValue::Integer((*f == 0.0) as i64),
OwnedValue::Text(text) => exec_boolean_not(&cast_text_to_numerical(text.as_str())),
OwnedValue::Text(text) => exec_boolean_not(&cast_text_to_real(text.as_str())),
_ => todo!(),
}
}

pub fn exec_concat(lhs: &OwnedValue, rhs: &OwnedValue) -> OwnedValue {
Copy link
Contributor

Choose a reason for hiding this comment

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

we can shorten this here (I know maybe unrelated change but if it's being changed anyway)

    if let OwnedValue::Agg(agg) = lhs {
        lhs = agg.final_value();
    }
// rhs..

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah true! Anyway I'm not planning to get this merged as is, I was using this branch as a mega-exploration to discover things

@pedrocarlo
Copy link
Contributor

Hey @jussisaurio, with the fuzzer I was trying to solve some issues with cast_text_to_numeric as well. I created a PR #1038. Still trying to port correctly the implementation from sqlite. Would appreciate some feedback with my exploration as well.

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.

3 participants