diff --git a/queries/eager_load.go b/queries/eager_load.go index 081aac4..962d722 100644 --- a/queries/eager_load.go +++ b/queries/eager_load.go @@ -206,9 +206,16 @@ func (l loadRelationshipState) loadRelationshipsRecurse(depth int, obj reflect.V } bkind := kindStruct - if reflect.Indirect(loadedObject).Kind() != reflect.Struct { + if derefed := reflect.Indirect(loadedObject); derefed.Kind() != reflect.Struct { bkind = kindPtrSliceStruct - loadedObject = loadedObject.Addr() + + // Convert away any helper slice types + // elemType is *elem (from []*elem or helperSliceType) + // sliceType is *[]*elem + elemType := derefed.Type().Elem() + sliceType := reflect.PtrTo(reflect.SliceOf(elemType)) + + loadedObject = loadedObject.Addr().Convert(sliceType) } return l.loadRelationships(depth+1, loadedObject.Interface(), bkind) } @@ -241,6 +248,9 @@ func collectLoaded(key string, loadingFrom reflect.Value) (reflect.Value, bindKi if loadedType.Elem().Kind() == reflect.Struct { bkind = kindStruct loadedType = reflect.SliceOf(loadedType) + } else { + // Ensure that we get rid of all the helper "XSlice" types + loadedType = reflect.SliceOf(loadedType.Elem()) } collection := reflect.MakeSlice(loadedType, 0, 0) diff --git a/queries/qm/query_mods.go b/queries/qm/query_mods.go index 89d31d4..6fa6e2f 100644 --- a/queries/qm/query_mods.go +++ b/queries/qm/query_mods.go @@ -123,6 +123,13 @@ func From(from string) QueryMod { } } +func ForceIndex( index string) QueryMod { + return func(q *queries.Query) { + queries.SetForceIndex(q, index) + } +} + + // Limit the number of returned rows func Limit(limit int) QueryMod { return func(q *queries.Query) { diff --git a/queries/query.go b/queries/query.go index 14f2d51..5b0ffbc 100644 --- a/queries/query.go +++ b/queries/query.go @@ -30,6 +30,7 @@ type Query struct { selectCols []string count bool from []string + forceindex string joins []join where []where in []in @@ -263,6 +264,11 @@ func SetLastWhereAsOr(q *Query) { q.where[len(q.where)-1].orSeparator = true } +// SetForceIndex sets the index to be used by the query +func SetForceIndex(q *Query, index string){ + q.forceindex = index +} + // SetLastInAsOr sets the or separator for the tail "IN" in the slice func SetLastInAsOr(q *Query) { if len(q.in) == 0 { diff --git a/queries/query_builders.go b/queries/query_builders.go index f884f91..e682877 100644 --- a/queries/query_builders.go +++ b/queries/query_builders.go @@ -76,7 +76,13 @@ func buildSelectQuery(q *Query) (*bytes.Buffer, []interface{}) { buf.WriteByte(')') } - fmt.Fprintf(buf, " FROM %s", strings.Join(strmangle.IdentQuoteSlice(q.dialect.LQ, q.dialect.RQ, q.from), ", ")) + if len(q.forceindex) > 0 { + fmt.Fprintf(buf, " FROM %s FORCE INDEX (%s)", strings.Join(strmangle.IdentQuoteSlice(q.dialect.LQ, q.dialect.RQ, q.from), ", "),q.forceindex) + + }else{ + fmt.Fprintf(buf, " FROM %s", strings.Join(strmangle.IdentQuoteSlice(q.dialect.LQ, q.dialect.RQ, q.from), ", ")) + + } if len(q.joins) > 0 { argsLen := len(args)