This is an automated email from the ASF dual-hosted git repository. rubenql pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push: new 32babcb90 [CALCITE-5079] Update code demo of tutorial 32babcb90 is described below commit 32babcb90aa5940bdd75760021abab6459a9cca4 Author: Ada Wang <wang4lun...@gmail.com> AuthorDate: Fri Apr 1 14:29:47 2022 +0800 [CALCITE-5079] Update code demo of tutorial --- site/_docs/tutorial.md | 81 ++++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/site/_docs/tutorial.md b/site/_docs/tutorial.md index 5eefce347..7b509bd62 100644 --- a/site/_docs/tutorial.md +++ b/site/_docs/tutorial.md @@ -197,17 +197,21 @@ schema, passing in the <code>directory</code> argument from the model file: {% highlight java %} public Schema create(SchemaPlus parentSchema, String name, Map<String, Object> operand) { - String directory = (String) operand.get("directory"); + final String directory = (String) operand.get("directory"); + final File base = + (File) operand.get(ModelHandler.ExtraOperand.BASE_DIRECTORY.camelName); + File directoryFile = new File(directory); + if (base != null && !directoryFile.isAbsolute()) { + directoryFile = new File(base, directory); + } String flavorName = (String) operand.get("flavor"); CsvTable.Flavor flavor; if (flavorName == null) { flavor = CsvTable.Flavor.SCANNABLE; } else { - flavor = CsvTable.Flavor.valueOf(flavorName.toUpperCase()); + flavor = CsvTable.Flavor.valueOf(flavorName.toUpperCase(Locale.ROOT)); } - return new CsvSchema( - new File(directory), - flavor); + return new CsvSchema(directoryFile, flavor); } {% endhighlight %} @@ -230,17 +234,15 @@ Here is the relevant code from <code>CsvSchema</code>, overriding the method in the <code>AbstractSchema</code> base class. {% highlight java %} -protected Map<String, Table> getTableMap() { +private Map<String, Table> createTableMap() { // Look for files in the directory ending in ".csv", ".csv.gz", ".json", // ".json.gz". - File[] files = directoryFile.listFiles( - new FilenameFilter() { - public boolean accept(File dir, String name) { - final String nameSansGz = trim(name, ".gz"); - return nameSansGz.endsWith(".csv") - || nameSansGz.endsWith(".json"); - } - }); + final Source baseSource = Sources.of(directoryFile); + File[] files = directoryFile.listFiles((dir, name) -> { + final String nameSansGz = trim(name, ".gz"); + return nameSansGz.endsWith(".csv") + || nameSansGz.endsWith(".json"); + }); if (files == null) { System.out.println("directory " + directoryFile + " not found"); files = new File[0]; @@ -248,31 +250,33 @@ protected Map<String, Table> getTableMap() { // Build a map from table name to table; each file becomes a table. final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder(); for (File file : files) { - String tableName = trim(file.getName(), ".gz"); - final String tableNameSansJson = trimOrNull(tableName, ".json"); - if (tableNameSansJson != null) { - JsonTable table = new JsonTable(file); - builder.put(tableNameSansJson, table); - continue; + Source source = Sources.of(file); + Source sourceSansGz = source.trim(".gz"); + final Source sourceSansJson = sourceSansGz.trimOrNull(".json"); + if (sourceSansJson != null) { + final Table table = new JsonScannableTable(source); + builder.put(sourceSansJson.relative(baseSource).path(), table); + } + final Source sourceSansCsv = sourceSansGz.trimOrNull(".csv"); + if (sourceSansCsv != null) { + final Table table = createTable(source); + builder.put(sourceSansCsv.relative(baseSource).path(), table); } - tableName = trim(tableName, ".csv"); - final Table table = createTable(file); - builder.put(tableName, table); } return builder.build(); } /** Creates different sub-type of table based on the "flavor" attribute. */ -private Table createTable(File file) { +private Table createTable(Source source) { switch (flavor) { case TRANSLATABLE: - return new CsvTranslatableTable(file, null); + return new CsvTranslatableTable(source, null); case SCANNABLE: - return new CsvScannableTable(file, null); + return new CsvScannableTable(source, null); case FILTERABLE: - return new CsvFilterableTable(file, null); + return new CsvFilterableTable(source, null); default: - throw new AssertionError("Unknown flavor " + flavor); + throw new AssertionError("Unknown flavor " + this.flavor); } } {% endhighlight %} @@ -413,12 +417,14 @@ passing in the <code>file</code> argument from the model file: {% highlight java %} public CsvTable create(SchemaPlus schema, String name, - Map<String, Object> map, RelDataType rowType) { - String fileName = (String) map.get("file"); - final File file = new File(fileName); + Map<String, Object> operand, @Nullable RelDataType rowType) { + String fileName = (String) operand.get("file"); + final File base = + (File) operand.get(ModelHandler.ExtraOperand.BASE_DIRECTORY.camelName); + final Source source = Sources.file(base, fileName); final RelProtoDataType protoRowType = rowType != null ? RelDataTypeImpl.proto(rowType) : null; - return new CsvScannableTable(file, protoRowType); + return new CsvScannableTable(source, protoRowType); } {% endhighlight %} @@ -519,6 +525,7 @@ Here is the rule in its entirety: {% highlight java %} public class CsvProjectTableScanRule extends RelRule<CsvProjectTableScanRule.Config> { + /** Creates a CsvProjectTableScanRule. */ protected CsvProjectTableScanRule(Config config) { super(config); @@ -540,7 +547,7 @@ public class CsvProjectTableScanRule fields)); } - private int[] getProjectFields(List<RexNode> exps) { + private static int[] getProjectFields(List<RexNode> exps) { final int[] fields = new int[exps.size()]; for (int i = 0; i < exps.size(); i++) { final RexNode exp = exps.get(i); @@ -554,17 +561,19 @@ public class CsvProjectTableScanRule } /** Rule configuration. */ + @Value.Immutable(singleton = false) public interface Config extends RelRule.Config { - Config DEFAULT = EMPTY + Config DEFAULT = ImmutableCsvProjectTableScanRule.Config.builder() .withOperandSupplier(b0 -> b0.operand(LogicalProject.class).oneInput(b1 -> b1.operand(CsvTableScan.class).noInputs())) - .as(Config.class); + .build(); @Override default CsvProjectTableScanRule toRule() { return new CsvProjectTableScanRule(this); } -} + } +} {% endhighlight %} The default instance of the rule resides in the `CsvRules` holder class: