1
1
package com .linkedin .hoptimator ;
2
2
3
+ import org .apache .calcite .rel .RelNode ;
3
4
import org .apache .calcite .sql .dialect .MysqlSqlDialect ;
4
5
import sqlline .SqlLine ;
5
6
import sqlline .CommandHandler ;
6
7
import sqlline .DispatchCallback ;
7
8
import org .jline .reader .Completer ;
8
-
9
- import org .apache . calcite . rel . RelNode ;
9
+ import org . slf4j . Logger ;
10
+ import org .slf4j . LoggerFactory ;
10
11
11
12
import com .linkedin .hoptimator .catalog .AvroConverter ;
12
13
import com .linkedin .hoptimator .catalog .Resource ;
15
16
import com .linkedin .hoptimator .planner .Pipeline ;
16
17
import com .linkedin .hoptimator .planner .PipelineRel ;
17
18
18
- import org .slf4j .Logger ;
19
- import org .slf4j .LoggerFactory ;
20
-
21
19
import java .util .ArrayList ;
22
20
import java .util .Collections ;
23
21
import java .util .List ;
28
26
29
27
public class HoptimatorCliApp {
30
28
private final Logger logger = LoggerFactory .getLogger (HoptimatorCliApp .class );
29
+ private final Properties properties ;
31
30
32
31
private SqlLine sqlline ;
33
32
33
+ public HoptimatorCliApp (Properties properties ) {
34
+ this .properties = properties ;
35
+ }
36
+
34
37
public static void main (String [] args ) throws Exception {
35
- HoptimatorCliApp app = new HoptimatorCliApp ();
38
+ HoptimatorCliApp app = new HoptimatorCliApp (new Properties () );
36
39
int result = app .run (args );
37
40
System .exit (result );
38
41
}
39
42
40
- protected int run (String [] args ) throws IOException {
43
+ public int run (String [] args ) throws IOException {
41
44
this .sqlline = new SqlLine ();
42
45
Scanner scanner = new Scanner (Thread .currentThread ().getContextClassLoader ().getResourceAsStream ("welcome.txt" ));
43
46
while (scanner .hasNext ()) {
@@ -52,6 +55,7 @@ protected int run(String[] args) throws IOException {
52
55
commandHandlers .add (new InsertCommandHandler ());
53
56
commandHandlers .add (new CheckCommandHandler ());
54
57
commandHandlers .add (new MermaidCommandHandler ());
58
+ commandHandlers .add (new ConfigCommandHandler ());
55
59
sqlline .updateCommandHandlers (commandHandlers );
56
60
return sqlline .begin (args , null , true ).ordinal ();
57
61
}
@@ -133,7 +137,7 @@ public void execute(String line, DispatchCallback dispatchCallback) {
133
137
134
138
String connectionUrl = sqlline .getConnectionMetadata ().getUrl ();
135
139
try {
136
- HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , new Properties () );
140
+ HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , properties );
137
141
RelNode plan = planner .logical (sql );
138
142
String avroSchema = AvroConverter .avro ("OutputNamespace" , "OutputName" , plan .getRowType ()).toString (true );
139
143
sqlline .output (avroSchema );
@@ -201,14 +205,15 @@ public void execute(String line, DispatchCallback dispatchCallback) {
201
205
String connectionUrl = sqlline .getConnectionMetadata ().getUrl ();
202
206
try {
203
207
InsertInto insertInto = parseInsertInto (sql );
204
- HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , new Properties () );
208
+ HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , properties );
205
209
PipelineRel plan = planner .pipeline (insertInto .query );
206
210
PipelineRel .Implementor impl = new PipelineRel .Implementor (plan );
207
211
HopTable sink = planner .database (insertInto .database )
208
212
.makeTable (insertInto .table , impl .rowType ());
209
213
Pipeline pipeline = impl .pipeline (sink );
210
214
// TODO provide generated avro schema to environment
211
- Resource .TemplateFactory templateFactory = new Resource .SimpleTemplateFactory (new Resource .DummyEnvironment ());
215
+ Resource .TemplateFactory templateFactory = new Resource .SimpleTemplateFactory (
216
+ new Resource .SimpleEnvironment (properties ).orIgnore ());
212
217
sqlline .output (pipeline .render (templateFactory ));
213
218
dispatchCallback .setToSuccess ();
214
219
} catch (Exception e ) {
@@ -275,7 +280,7 @@ public void execute(String line, DispatchCallback dispatchCallback) {
275
280
String connectionUrl = sqlline .getConnectionMetadata ().getUrl ();
276
281
try {
277
282
InsertInto insertInto = parseInsertInto (sql );
278
- HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , new Properties () );
283
+ HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , properties );
279
284
PipelineRel plan = planner .pipeline (insertInto .query );
280
285
sqlline .output ("PLAN:" );
281
286
sqlline .output (plan .explain ());
@@ -378,7 +383,7 @@ public void execute(String line, DispatchCallback dispatchCallback) {
378
383
throw new IllegalArgumentException ("Expected one of 'not', 'empty', or 'value'" );
379
384
}
380
385
381
- HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , new Properties () );
386
+ HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , properties );
382
387
PipelineRel plan = planner .pipeline (query );
383
388
PipelineRel .Implementor impl = new PipelineRel .Implementor (plan );
384
389
String pipelineSql = impl .query ().sql (MysqlSqlDialect .DEFAULT );
@@ -470,8 +475,7 @@ public void execute(String line, DispatchCallback dispatchCallback) {
470
475
String connectionUrl = sqlline .getConnectionMetadata ().getUrl ();
471
476
try {
472
477
InsertInto insertInto = parseInsertInto (sql );
473
- HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl ,
474
- new Properties ());
478
+ HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , properties );
475
479
PipelineRel plan = planner .pipeline (insertInto .query );
476
480
PipelineRel .Implementor impl = new PipelineRel .Implementor (plan );
477
481
HopTable sink = planner .database (insertInto .database )
@@ -603,7 +607,7 @@ public void execute(String line, DispatchCallback dispatchCallback) {
603
607
String connectionUrl = sqlline .getConnectionMetadata ().getUrl ();
604
608
try {
605
609
InsertInto insertInto = parseInsertInto (sql );
606
- HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , new Properties () );
610
+ HoptimatorPlanner planner = HoptimatorPlanner .fromModelFile (connectionUrl , properties );
607
611
PipelineRel plan = planner .pipeline (insertInto .query );
608
612
PipelineRel .Implementor impl = new PipelineRel .Implementor (plan );
609
613
HopTable sink = planner .database (insertInto .database )
@@ -628,6 +632,79 @@ public boolean echoToFile() {
628
632
}
629
633
}
630
634
635
+ private class ConfigCommandHandler implements CommandHandler {
636
+
637
+ @ Override
638
+ public String getName () {
639
+ return "config" ;
640
+ }
641
+
642
+ @ Override
643
+ public List <String > getNames () {
644
+ return Collections .singletonList (getName ());
645
+ }
646
+
647
+ @ Override
648
+ public String getHelpText () {
649
+ return "Export a Hoptimator variable to templates, operators, etc" ;
650
+ }
651
+
652
+ @ Override
653
+ public String matches (String line ) {
654
+ String cmd = line ;
655
+ if (startsWith (cmd , SqlLine .COMMAND_PREFIX )) {
656
+ cmd = cmd .substring (1 );
657
+ }
658
+
659
+ if (startsWith (cmd , "config " )) {
660
+ cmd = cmd .substring ("config " .length ());
661
+ return cmd ;
662
+ } else if (startsWith (cmd , "config" )) {
663
+ cmd = cmd .substring ("config" .length ());
664
+ return cmd ;
665
+ }
666
+
667
+ return null ;
668
+ }
669
+
670
+ @ Override
671
+ public void execute (String line , DispatchCallback dispatchCallback ) {
672
+ String cmd = line ;
673
+ if (startsWith (cmd , SqlLine .COMMAND_PREFIX )) {
674
+ cmd = cmd .substring (1 );
675
+ }
676
+
677
+ if (startsWith (cmd , "config " )) {
678
+ cmd = cmd .substring ("config " .length ());
679
+ } else if (startsWith (cmd , "config" )) {
680
+ cmd = cmd .substring ("config" .length ());
681
+ }
682
+
683
+ String []split = cmd .split ("[\\ s=]+" , 2 );
684
+
685
+ if (split .length != 2 ) {
686
+ sqlline .output ("Currently defined configs:" );
687
+ properties .forEach ((k , v ) -> sqlline .output (k .toString () + "=" + v .toString ()));
688
+ } else {
689
+ String k = split [0 ];
690
+ String v = split [1 ];
691
+ sqlline .output ("Setting config " + k + " = " + v );
692
+ properties .setProperty (k , v );
693
+ }
694
+ dispatchCallback .setToSuccess ();
695
+ }
696
+
697
+ @ Override
698
+ public List <Completer > getParameterCompleters () {
699
+ return Collections .emptyList ();
700
+ }
701
+
702
+ @ Override
703
+ public boolean echoToFile () {
704
+ return false ;
705
+ }
706
+ }
707
+
631
708
// case-insensitive prefix match
632
709
static boolean startsWith (String s , String prefix ) {
633
710
return s .matches ("(?i)" + prefix + ".*" );
0 commit comments