Skip to content

Commit 23b8b43

Browse files
authored
Merge pull request #1 from feldera/feldera
[feldera] first commit: add preliminary support
2 parents 04f0b49 + 289a68b commit 23b8b43

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2682
-2
lines changed

pom.xml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,13 @@
329329
</dependency>
330330
<dependency>
331331
<groupId>org.slf4j</groupId>
332-
<artifactId> slf4j-simple</artifactId>
333-
<version>2.0.6</version>
332+
<artifactId>slf4j-api</artifactId>
333+
<version>2.0.16</version>
334+
</dependency>
335+
<dependency>
336+
<groupId>org.slf4j</groupId>
337+
<artifactId>slf4j-simple</artifactId>
338+
<version>2.0.16</version>
334339
</dependency>
335340
<dependency>
336341
<groupId>ru.yandex.clickhouse</groupId>
@@ -378,6 +383,12 @@
378383
<artifactId>flight-sql-jdbc-driver</artifactId>
379384
<version>16.1.0</version>
380385
</dependency>
386+
<dependency>
387+
<groupId>junit</groupId>
388+
<artifactId>junit</artifactId>
389+
<version>4.13.1</version>
390+
<scope>compile</scope>
391+
</dependency>
381392
</dependencies>
382393
<reporting>
383394
<plugins>

src/sqlancer/Main.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import sqlancer.databend.DatabendProvider;
3434
import sqlancer.doris.DorisProvider;
3535
import sqlancer.duckdb.DuckDBProvider;
36+
import sqlancer.feldera.FelderaProvider;
3637
import sqlancer.h2.H2Provider;
3738
import sqlancer.hsqldb.HSQLDBProvider;
3839
import sqlancer.mariadb.MariaDBProvider;
@@ -734,6 +735,7 @@ private static void checkForIssue799(List<DatabaseProvider<?, ?, ?>> providers)
734735
providers.add(new DatabendProvider());
735736
providers.add(new DorisProvider());
736737
providers.add(new DuckDBProvider());
738+
providers.add(new FelderaProvider());
737739
providers.add(new H2Provider());
738740
providers.add(new HSQLDBProvider());
739741
providers.add(new MariaDBProvider());
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package sqlancer.feldera;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.fasterxml.jackson.databind.node.ObjectNode;
5+
import sqlancer.SQLancerDBConnection;
6+
import sqlancer.feldera.client.FelderaClient;
7+
import sqlancer.feldera.client.FelderaPipeline;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import java.util.Map;
12+
13+
public class FelderaConnection implements SQLancerDBConnection {
14+
private final FelderaClient client;
15+
private final String pipelineName;
16+
private final List<String> inserts;
17+
private boolean ready = false;
18+
private String ddl;
19+
20+
public FelderaConnection(String url, String pipelineName) {
21+
this.client = new FelderaClient(url);
22+
this.pipelineName = pipelineName;
23+
this.inserts = new ArrayList<>();
24+
this.ddl = "";
25+
}
26+
27+
public void prepare() throws Exception {
28+
if (!ready) {
29+
ObjectMapper mapper = new ObjectMapper();
30+
ObjectNode node = mapper.createObjectNode();
31+
32+
node.put("name", this.pipelineName);
33+
node.put("description", "sqlancerTest");
34+
String ddlWithInserts = ddl + "--" + String.join("\n--", inserts);
35+
node.put("program_code", ddlWithInserts);
36+
node.putObject("runtime_config");
37+
node.putObject("program_config");
38+
39+
this.client.createPipeline(pipelineName, node.toString());
40+
this.client.start(this.pipelineName);
41+
42+
for (String insert : this.inserts) {
43+
this.client.exec(this.pipelineName, insert);
44+
}
45+
46+
ready = true;
47+
}
48+
}
49+
50+
public String getPipelineName() {
51+
return this.pipelineName;
52+
}
53+
54+
public FelderaClient getClient() {
55+
return this.client;
56+
}
57+
58+
@Override
59+
public String getDatabaseVersion() throws Exception {
60+
int x = this.client.getPipeline(this.pipelineName).getVersion();
61+
return Integer.toString(x);
62+
}
63+
64+
@Override
65+
public void close() throws Exception {
66+
if (ready) {
67+
this.client.shutdown(pipelineName);
68+
}
69+
}
70+
71+
public FelderaPipeline get() throws Exception {
72+
return this.client.getPipeline(pipelineName);
73+
}
74+
75+
public void buffer(String query) throws Exception {
76+
if (query.startsWith("INSERT")) {
77+
this.inserts.add(query);
78+
} else {
79+
this.ddl += query;
80+
}
81+
}
82+
83+
public Map<String, Object> execute(String query) throws Exception {
84+
return this.client.exec(this.pipelineName, query);
85+
}
86+
87+
public void shutdown() throws Exception {
88+
this.client.shutdown(this.pipelineName);
89+
}
90+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package sqlancer.feldera;
2+
3+
import sqlancer.common.query.ExpectedErrors;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class FelderaExpectedError {
9+
private FelderaExpectedError() {
10+
}
11+
12+
public static List<String> getExpectedErrors() {
13+
List<String> errors = new ArrayList<>();
14+
errors.add("panic message:");
15+
return errors;
16+
}
17+
18+
public static ExpectedErrors expectedErrors() {
19+
ExpectedErrors res = new ExpectedErrors();
20+
res.addAll(getExpectedErrors());
21+
return res;
22+
}
23+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package sqlancer.feldera;
2+
3+
import sqlancer.ExecutionTimer;
4+
import sqlancer.GlobalState;
5+
import sqlancer.common.query.Query;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
public class FelderaGlobalState extends GlobalState<FelderaOptions, FelderaSchema, FelderaConnection> {
11+
List<String> views = new ArrayList<>();
12+
13+
@Override
14+
protected void executeEpilogue(Query<?> q, boolean success, ExecutionTimer timer) throws Exception {
15+
boolean logExecutionTime = getOptions().logExecutionTime();
16+
if (success && getOptions().printSucceedingStatements()) {
17+
System.out.println(q.getQueryString());
18+
}
19+
if (logExecutionTime) {
20+
getLogger().writeCurrent(" -- " + timer.end().asString());
21+
}
22+
if (q.couldAffectSchema()) {
23+
updateSchema();
24+
}
25+
}
26+
27+
@Override
28+
public void updateSchema() {
29+
; // do nothing
30+
}
31+
32+
@Override
33+
public FelderaSchema getSchema() {
34+
return super.getSchema();
35+
}
36+
37+
@Override
38+
protected FelderaSchema readSchema() throws Exception {
39+
return FelderaSchema.fromConnection(getConnection());
40+
}
41+
42+
public void addTable(FelderaSchema.FelderaTable table) {
43+
FelderaSchema sch = getSchema();
44+
if (sch == null) {
45+
sch = new FelderaSchema(getConnection().getPipelineName());
46+
}
47+
setSchema(sch.addTable(table));
48+
}
49+
50+
public void addView(String view) {
51+
this.views.add(view);
52+
}
53+
54+
public List<String> getViews() {
55+
return this.views;
56+
}
57+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package sqlancer.feldera;
2+
3+
import sqlancer.common.log.Loggable;
4+
import sqlancer.common.log.LoggableFactory;
5+
import sqlancer.common.log.LoggedString;
6+
import sqlancer.common.query.ExpectedErrors;
7+
import sqlancer.common.query.Query;
8+
import sqlancer.feldera.query.FelderaOtherQuery;
9+
import sqlancer.feldera.query.FelderaQueryAdapter;
10+
11+
import java.io.PrintWriter;
12+
import java.io.StringWriter;
13+
14+
public class FelderaLoggableFactory extends LoggableFactory {
15+
@Override
16+
protected Loggable createLoggable(String input, String suffix) {
17+
String completeString = input.trim();
18+
if (!input.endsWith(";")) {
19+
completeString += ";";
20+
}
21+
if (suffix != null && !suffix.isEmpty()) {
22+
completeString += suffix;
23+
}
24+
return new LoggedString(completeString);
25+
}
26+
27+
@Override
28+
public FelderaQueryAdapter getQueryForStateToReproduce(String queryString) {
29+
return new FelderaOtherQuery(queryString, FelderaExpectedError.expectedErrors());
30+
}
31+
32+
@Override
33+
public FelderaQueryAdapter commentOutQuery(Query<?> query) {
34+
String queryString = query.getQueryString();
35+
String newQueryString = "-- " + queryString;
36+
ExpectedErrors errors = new ExpectedErrors();
37+
return new FelderaOtherQuery(newQueryString, errors);
38+
}
39+
40+
@Override
41+
protected Loggable infoToLoggable(String time, String pipelineName, String databaseVersion, long seedValue) {
42+
String sb = "-- Time: " + time + "\n" + "-- Pipeline: " + pipelineName + "\n " + "-- Pipeline version: "
43+
+ databaseVersion + "\n" + "-- seed value: " + seedValue + "\n";
44+
return new LoggedString(sb);
45+
}
46+
47+
@Override
48+
public Loggable convertStacktraceToLoggable(Throwable throwable) {
49+
StringWriter sw = new StringWriter();
50+
PrintWriter pw = new PrintWriter(sw);
51+
throwable.printStackTrace(pw);
52+
return new LoggedString("--" + sw.toString().replace("\n", "\n--"));
53+
}
54+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package sqlancer.feldera;
2+
3+
import java.util.List;
4+
5+
import com.beust.jcommander.Parameter;
6+
import com.beust.jcommander.Parameters;
7+
8+
import sqlancer.DBMSSpecificOptions;
9+
10+
@Parameters(separators = "=", commandDescription = "Feldera (default " + FelderaOptions.DEFAULT_URL + ")")
11+
public class FelderaOptions implements DBMSSpecificOptions<FelderaOracleFactory> {
12+
13+
public static final String DEFAULT_URL = "http://127.0.0.1:8080";
14+
15+
@Parameter(names = "--oracle", description = "Specifies which test oracle should be used for Feldera")
16+
public List<FelderaOracleFactory> oracle = List.of(FelderaOracleFactory.NOREC);
17+
18+
@Parameter(names = "--connection-url", description = "Specifies the URL for connecting to the Feldera", arity = 1)
19+
public String connection_url = DEFAULT_URL;
20+
21+
@Override
22+
public List<FelderaOracleFactory> getTestOracleFactory() {
23+
return oracle;
24+
}
25+
26+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package sqlancer.feldera;
2+
3+
import sqlancer.OracleFactory;
4+
import sqlancer.feldera.oracle.FelderaNoRECOracle;
5+
import sqlancer.common.oracle.TestOracle;
6+
7+
public enum FelderaOracleFactory implements OracleFactory<FelderaGlobalState> {
8+
NOREC {
9+
@Override
10+
public TestOracle<FelderaGlobalState> create(FelderaGlobalState globalState) {
11+
return new FelderaNoRECOracle(globalState);
12+
}
13+
},
14+
}

0 commit comments

Comments
 (0)