|
1 | 1 | package semantic |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "context" |
5 | 4 | "errors" |
6 | 5 | "fmt" |
7 | 6 | "net/url" |
@@ -101,8 +100,12 @@ func (t *translator) semFromEntity(entity ast.FromEntity, alias *ast.TableAlias, |
101 | 100 | } |
102 | 101 | op, def := t.semFromName(entity, entity.Text, args) |
103 | 102 | if op, ok := op.(*sem.FileScan); ok { |
104 | | - if cols, ok := t.fileScanColumns(op); ok { |
105 | | - schema := schema(&staticSchema{def, cols}) |
| 103 | + if rec := super.TypeRecordOf(op.Type); rec != nil { |
| 104 | + var columns []string |
| 105 | + for _, f := range rec.Fields { |
| 106 | + columns = append(columns, f.Name) |
| 107 | + } |
| 108 | + schema := schema(&staticSchema{def, columns}) |
106 | 109 | seq, schema, err := derefSchemaWithAlias(op, schema, alias, sem.Seq{op}) |
107 | 110 | if err != nil { |
108 | 111 | t.error(alias, err) |
@@ -145,33 +148,6 @@ func (t *translator) fromCTE(entity ast.FromEntity, c *ast.SQLCTE, alias *ast.Ta |
145 | 148 | return seq, schema |
146 | 149 | } |
147 | 150 |
|
148 | | -// XXX this should find a type from the schema rather than the columns |
149 | | -func (t *translator) fileScanColumns(op *sem.FileScan) ([]string, bool) { |
150 | | - if op.Format != "parquet" { |
151 | | - return nil, false |
152 | | - } |
153 | | - uri, err := storage.ParseURI(op.Path) |
154 | | - if err != nil { |
155 | | - return nil, false |
156 | | - } |
157 | | - ctx, cancel := context.WithCancel(t.ctx) |
158 | | - defer cancel() |
159 | | - sr, err := t.env.Engine().Get(ctx, uri) |
160 | | - if err != nil { |
161 | | - return nil, false |
162 | | - } |
163 | | - defer sr.Close() |
164 | | - op.Type = parquetio.Type(t.sctx, sr) |
165 | | - if op.Type == nil { |
166 | | - return nil, false |
167 | | - } |
168 | | - var cols []string |
169 | | - for _, f := range op.Type.(*super.TypeRecord).Fields { |
170 | | - cols = append(cols, f.Name) |
171 | | - } |
172 | | - return cols, true |
173 | | -} |
174 | | - |
175 | 151 | func (t *translator) semFromExpr(entity *ast.ExprEntity, args []ast.OpArg, seq sem.Seq) (sem.Seq, string) { |
176 | 152 | expr := t.semExpr(entity.Expr) |
177 | 153 | val, ok := t.maybeEval(expr) |
@@ -260,13 +236,34 @@ func (t *translator) semFile(n ast.Node, name string, args []ast.OpArg) sem.Op { |
260 | 236 | if format == "" { |
261 | 237 | format = sio.FormatFromPath(name) |
262 | 238 | } |
| 239 | + typ, err := t.fileType(name, format) |
| 240 | + if err != nil { |
| 241 | + t.error(n, err) |
| 242 | + } |
263 | 243 | return &sem.FileScan{ |
264 | 244 | Node: n, |
| 245 | + Type: typ, |
265 | 246 | Path: name, |
266 | 247 | Format: format, |
267 | 248 | } |
268 | 249 | } |
269 | 250 |
|
| 251 | +func (t *translator) fileType(path, format string) (super.Type, error) { |
| 252 | + if format != "parquet" { |
| 253 | + return nil, nil |
| 254 | + } |
| 255 | + uri, err := storage.ParseURI(path) |
| 256 | + if err != nil { |
| 257 | + return nil, err |
| 258 | + } |
| 259 | + r, err := t.env.Engine().Get(t.ctx, uri) |
| 260 | + if err != nil { |
| 261 | + return nil, err |
| 262 | + } |
| 263 | + defer r.Close() |
| 264 | + return parquetio.Type(t.sctx, r), nil |
| 265 | +} |
| 266 | + |
270 | 267 | func (t *translator) semFromFileGlob(globLoc ast.Node, pattern string, args []ast.OpArg) sem.Op { |
271 | 268 | names, err := filepath.Glob(pattern) |
272 | 269 | if err != nil { |
|
0 commit comments