Skip to content

Commit

Permalink
Extend support of group by and order by clause
Browse files Browse the repository at this point in the history
Signed-off-by: Stefano Scafiti <stefano.scafiti96@gmail.com>
  • Loading branch information
ostafen committed May 14, 2024
1 parent 0c8204a commit fd9d1bb
Show file tree
Hide file tree
Showing 13 changed files with 1,362 additions and 576 deletions.
86 changes: 79 additions & 7 deletions embedded/sql/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,61 @@ func (i *Index) enginePrefix() []byte {
return i.table.catalog.enginePrefix
}

func (i *Index) sortableUsing(colID uint32, rangesByColID map[uint32]*typedValueRange) bool {
func (i *Index) coversOrdCols(ordCols []*OrdCol, rangesByColID map[uint32]*typedValueRange) bool {
if !ordColumnsHaveSameDirection(ordCols) {
return false
}
return i.hasPrefix(i.cols, ordCols) || i.sortableUsing(ordCols, rangesByColID)
}

func ordColumnsHaveSameDirection(cols []*OrdCol) bool {
if len(cols) == 0 {
return true
}

desc := cols[0].descOrder
for _, ordCol := range cols[1:] {
if ordCol.descOrder != desc {
return false
}
}
return true
}

func (i *Index) hasPrefix(columns []*Column, ordCols []*OrdCol) bool {
if len(ordCols) > len(columns) {
return false
}

for j, ordCol := range ordCols {
aggFn, _, colName := ordCol.sel.resolve(i.table.Name())
if len(aggFn) > 0 {
return false
}

col, err := i.table.GetColumnByName(colName)
if err != nil || col.id != columns[j].id {
return false
}
}
return true
}

func (i *Index) sortableUsing(columns []*OrdCol, rangesByColID map[uint32]*typedValueRange) bool {
// all columns before colID must be fixedValues otherwise the index can not be used
for _, col := range i.cols {
if col.id == colID {
return true
aggFn, _, colName := columns[0].sel.resolve(i.table.Name())
if len(aggFn) > 0 {
return false
}

firstCol, err := i.table.GetColumnByName(colName)
if err != nil {
return false
}

for j, col := range i.cols {
if col.id == firstCol.id {
return i.hasPrefix(i.cols[j:], columns)
}

colRange, ok := rangesByColID[col.id]
Expand Down Expand Up @@ -1255,20 +1305,30 @@ func EncodeRawValueAsKey(val interface{}, colType SQLValueType, maxLen int) ([]b
}

func EncodeValue(val TypedValue, colType SQLValueType, maxLen int) ([]byte, error) {
return EncodeRawValue(val.RawValue(), colType, maxLen)
return EncodeRawValue(val.RawValue(), colType, maxLen, false)
}

func EncodeNullableValue(val TypedValue, colType SQLValueType, maxLen int) ([]byte, error) {
return EncodeRawValue(val.RawValue(), colType, maxLen, true)
}

// EncodeRawValue encode a value in a byte format. This is the internal binary representation of a value. Can be decoded with DecodeValue.
func EncodeRawValue(val interface{}, colType SQLValueType, maxLen int) ([]byte, error) {
func EncodeRawValue(val interface{}, colType SQLValueType, maxLen int, nullable bool) ([]byte, error) {
convVal, err := mayApplyImplicitConversion(val, colType)
if err != nil {
return nil, err
}

if convVal == nil {
if convVal == nil && !nullable {
return nil, ErrInvalidValue
}

if convVal == nil {
encv := make([]byte, EncLenLen)
binary.BigEndian.PutUint32(encv[:], uint32(0))
return encv, nil
}

switch colType {
case VarcharType:
{
Expand Down Expand Up @@ -1405,11 +1465,23 @@ func DecodeValueLength(b []byte) (int, int, error) {
}

func DecodeValue(b []byte, colType SQLValueType) (TypedValue, int, error) {
return decodeValue(b, colType, false)
}

func DecodeNullableValue(b []byte, colType SQLValueType) (TypedValue, int, error) {
return decodeValue(b, colType, true)
}

func decodeValue(b []byte, colType SQLValueType, nullable bool) (TypedValue, int, error) {
vlen, voff, err := DecodeValueLength(b)
if err != nil {
return nil, 0, err
}

if vlen == 0 && nullable {
return &NullValue{t: colType}, voff, nil
}

switch colType {
case VarcharType:
{
Expand Down
6 changes: 4 additions & 2 deletions embedded/sql/dummy_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ SPDX-License-Identifier: BUSL-1.1
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://mariadb.com/bsl11/
https://mariadb.com/bsl11/
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -15,7 +15,9 @@ limitations under the License.
*/
package sql

import "context"
import (
"context"
)

type dummyDataSource struct {
inferParametersFunc func(ctx context.Context, tx *SQLTx, params map[string]SQLValueType) error
Expand Down
22 changes: 2 additions & 20 deletions embedded/sql/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ var ErrInvalidNumberOfValues = errors.New("invalid number of values provided")
var ErrInvalidValue = errors.New("invalid value provided")
var ErrInferredMultipleTypes = errors.New("inferred multiple types")
var ErrExpectingDQLStmt = errors.New("illegal statement. DQL statement expected")
var ErrLimitedOrderBy = errors.New("order by is limited to one column")
var ErrLimitedGroupBy = errors.New("group by requires ordering by the grouping column")
var ErrColumnMustAppearInGroupByOrAggregation = errors.New("must appear in the group by clause or be used in an aggregated function")
var ErrIllegalMappedKey = errors.New("error illegal mapped key")
var ErrCorruptedData = store.ErrCorruptedData
var ErrBrokenCatalogColSpecExpirable = fmt.Errorf("%w: catalog column entry set as expirable", ErrCorruptedData)
Expand Down Expand Up @@ -514,24 +513,7 @@ func (e *Engine) queryAll(ctx context.Context, tx *SQLTx, sql string, params map
}
defer reader.Close()

return readAllRows(ctx, reader)
}

func readAllRows(ctx context.Context, reader RowReader) ([]*Row, error) {
rows := make([]*Row, 0, 100)
for {
row, err := reader.Read(ctx)
if err == ErrNoMoreRows {
break
}

if err != nil {
return nil, err
}

rows = append(rows, row)
}
return rows, nil
return ReadAllRows(ctx, reader)
}

func (e *Engine) Query(ctx context.Context, tx *SQLTx, sql string, params map[string]interface{}) (RowReader, error) {
Expand Down
Loading

0 comments on commit fd9d1bb

Please sign in to comment.