-
-
Notifications
You must be signed in to change notification settings - Fork 210
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
adding json_table
function
#1142
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good start, see comments
sql/plan/json_table.go
Outdated
} | ||
|
||
// NewJSONTable creates a new in memory table from the JSON formatted data, a jsonpath path string, and table spec. | ||
func NewJSONTable(data []byte, path string, spec *sqlparser.TableSpec, alias sqlparser.TableIdent, schema sql.PrimaryKeySchema) (sql.Node, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in the other PR for vitess, this needs to take an expression for the JSON data, not a []byte
Also sqlparser.* should not make it down to this layer of the code, all that translation should be handled in parse.go
rowIdx uint64 | ||
} | ||
|
||
var _ sql.Table = &JSONTable{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might consider modelling this as a sql.TableFunction instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did originally, but I had trouble implementing the NewInstance
method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs more tests, missing some necessary things
enginetest/evaluation.go
Outdated
@@ -495,6 +495,8 @@ func WidenRow(sch sql.Schema, row sql.Row) sql.Row { | |||
vw = uint64(x) | |||
case float32: | |||
vw = float64(x) | |||
case float64: | |||
vw = float64(float32(x)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are rounding errors when using float64
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There really shouldn't be, this is a sign of a bug
Floats should round-trip with no precision loss
Does it come from parsing JSON?
enginetest/memory_engine_test.go
Outdated
@@ -111,6 +111,11 @@ func TestJoinQueries(t *testing.T) { | |||
enginetest.TestJoinQueries(t, enginetest.NewMemoryHarness("simple", 1, testNumPartitions, true, nil)) | |||
} | |||
|
|||
// TestJoinQueries runs the canonical test queries against a single threaded index enabled harness. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy pasta error
"github.com/dolthub/go-mysql-server/sql" | ||
) | ||
|
||
var JSONTableQueryTests = []QueryTest{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need some tests joining json tables to physical tables
If they don't work, add skipped tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also tests where the expression for json data comes from a column, not a string literal
sql/plan/json_table.go
Outdated
func (t *JSONTable) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) { | ||
// TODO: need to resolve function calls like concat() | ||
// data must evaluate to JSON string | ||
data, err := t.dataExpr.Eval(ctx, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to eval with a row
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking better, the table iteration needs a little love
enginetest/evaluation.go
Outdated
@@ -495,6 +495,8 @@ func WidenRow(sch sql.Schema, row sql.Row) sql.Row { | |||
vw = uint64(x) | |||
case float32: | |||
vw = float64(x) | |||
case float64: | |||
vw = float64(float32(x)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There really shouldn't be, this is a sign of a bug
Floats should round-trip with no precision loss
Does it come from parsing JSON?
sql/plan/json_table.go
Outdated
|
||
// RowIter implements the sql.Node interface | ||
func (t *JSONTable) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) { | ||
// TODO: need to resolve function calls like concat() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO is out of date, or no?
sql/plan/json_table.go
Outdated
if err != nil { | ||
return nil, err | ||
} | ||
strData, ok := data.(string) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't cast to a string like this, use Type.Convert()
sql/plan/json_table.go
Outdated
} | ||
|
||
// Fill in table with data | ||
for colIdx, p := range t.colPaths { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't do any of this iteration in RowIter, and don't store it all in memory
Do it one row at a time in iter.Next()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, nice work
|
||
var JSONTableQueryTests = []QueryTest{ | ||
{ | ||
Query: "SELECT * FROM JSON_TABLE(NULL,\"$[*]\" COLUMNS(x int path \"$.a\")) as t;", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For all these tests, use '
instead of "
for your quote delimiter (except where required because it's a json string).
Consider using backtick quoted golang strings so you don't need to escape "
in json strings either.
Adds some support for
json_table
function, which generates a table given a JSON string and column definitions.Fix for: dolthub/dolt#2163
TODO:
NESTED
FOR ORDINALITY
ON EMPTY
ON ERROR