diff --git a/executor.go b/executor.go index f99a0f667..6523ce925 100644 --- a/executor.go +++ b/executor.go @@ -322,6 +322,8 @@ func (e *executor) safeCopy(resp QueryResponse) (out QueryResponse) { safe[i] = v.Clone() } out.Results = append(out.Results, safe) + case DistinctTimestamp: + out.Results = append(out.Results, x) default: panic(fmt.Sprintf("handle %T here", v)) } @@ -1498,6 +1500,7 @@ func (e *executor) executeDistinctShard(ctx context.Context, qcx *Qcx, index str if field == nil { return nil, ErrFieldNotFound } + bsig := field.bsiGroup(fieldName) if bsig == nil { result = &Row{ @@ -1534,9 +1537,25 @@ func (e *executor) executeDistinctShard(ctx context.Context, qcx *Qcx, index str if bsig == nil { return executeDistinctShardSet(ctx, qcx, idx, fieldName, shard, filterBitmap) } + if field.Options().Type == FieldTypeTimestamp { + r, err := executeDistinctShardBSI(ctx, qcx, idx, fieldName, shard, bsig, filterBitmap) + if err != nil { + return nil, err + } + results := make([]string, len(r.Pos.Columns())) + for i, val := range r.Pos.Columns() { + results[i] = time.Unix(0, (int64(val)+int64(bsig.Base))*TimeUnitNanos(field.options.TimeUnit)).UTC().Format(time.RFC3339Nano) + } + return DistinctTimestamp{Name: fieldName, Values: results}, nil + } return executeDistinctShardBSI(ctx, qcx, idx, fieldName, shard, bsig, filterBitmap) } +type DistinctTimestamp struct { + Values []string + Name string +} + func executeDistinctShardSet(ctx context.Context, qcx *Qcx, idx *Index, fieldName string, shard uint64, filterBitmap *roaring.Bitmap) (result *Row, err0 error) { index := idx.Name() tx, finisher, err := qcx.GetTx(Txo{Write: !writable, Index: idx, Shard: shard}) diff --git a/server/pg.go b/server/pg.go index c2522f286..2a55bc3e1 100644 --- a/server/pg.go +++ b/server/pg.go @@ -155,6 +155,24 @@ type PilosaQueryHandler struct { sqlVersion SqlVersion } +func pgWriteDistinctTimestamp(w pg.QueryResultWriter, val pilosa.DistinctTimestamp) error { + err := w.WriteHeader(pg.ColumnInfo{ + Name: val.Name, + Type: pg.TypeCharoid, + }) + if err != nil { + return errors.Wrap(err, "writing result header") + } + + for _, k := range val.Values { + err = w.WriteRowText(k) + if err != nil { + return errors.Wrap(err, "writing key") + } + } + return nil +} + func pgWriteRow(w pg.QueryResultWriter, row *pilosa.Row) error { err := w.WriteHeader(pg.ColumnInfo{ Name: "_id", @@ -551,7 +569,8 @@ func pgWriteResult(w pg.QueryResultWriter, result interface{}) error { } return nil - + case pilosa.DistinctTimestamp: + return pgWriteDistinctTimestamp(w, result) case nil: return nil