SQL: Simplify expression ID generation (elastic/x-pack-elasticsearch#3466)

Replaces the `ExpressionIdGenerator` class with a static method and drops
the `jvmId` field from the `ExpressionId` altogether because it isn't needed.

We still have the potential to roll over expression ids if the server lives for
a long time but it is quite unlikely and rolling over only matters if we roll
over in the same query. So long as each expression id is unique to a
particular query we're fine.

Original commit: elastic/x-pack-elasticsearch@fe3d7f7216
This commit is contained in:
Nik Everett 2018-01-09 11:16:31 -05:00 committed by GitHub
parent 4009ba24b6
commit 4d6b58495d
6 changed files with 41 additions and 45 deletions

View File

@ -6,40 +6,44 @@
package org.elasticsearch.xpack.sql.expression;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
/**
* Unique identifier for an expression.
* <p>
* We use an {@link AtomicLong} to guarantee that they are unique
* and that they produce reproduceable values when run in subsequent
* tests. They don't produce reproduceable values in production, but
* you rarely debug with them in production and commonly do so in
* tests.
*/
public class ExpressionId {
private static final AtomicLong COUNTER = new AtomicLong();
private final long id;
private final int id;
private final String jvmId;
ExpressionId(int id, String jvmId) {
this.id = id;
this.jvmId = jvmId;
public ExpressionId() {
this.id = COUNTER.incrementAndGet();
}
@Override
public int hashCode() {
return Objects.hash(id, jvmId);
return Objects.hash(id);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
if (obj == this) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
ExpressionId other = (ExpressionId) obj;
return id == other.id
&& Objects.equals(jvmId, other.jvmId);
return id == other.id;
}
@Override
public String toString() {
return String.valueOf(id);
//#+ jvmId;
return Long.toString(id);
}
}

View File

@ -1,27 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
//TODO: this class is thread-safe but used across multiple sessions might cause the
// id to roll over and potentially generate an already assigned id
// making this session scope would simplify things
// (which also begs the question on whether thread-safety is needed than)
// TODO: hook this into SqlSession#SessionContext
public class ExpressionIdGenerator {
private static final AtomicInteger GLOBAL_ID = new AtomicInteger();
private static final String JVM_ID = "@" + UUID.randomUUID().toString();
public static final ExpressionId EMPTY = new ExpressionId(-1, "@<empty>");
public static ExpressionId newId() {
return new ExpressionId(GLOBAL_ID.getAndIncrement(), JVM_ID);
}
}

View File

@ -23,7 +23,7 @@ public abstract class NamedExpression extends Expression {
public NamedExpression(Location location, String name, List<Expression> children, ExpressionId id, boolean synthetic) {
super(location, children);
this.name = name;
this.id = (id == null ? ExpressionIdGenerator.newId() : id);
this.id = id == null ? new ExpressionId() : id;
this.synthetic = synthetic;
}

View File

@ -23,7 +23,7 @@ public abstract class SubQueryExpression extends Expression {
public SubQueryExpression(Location location, LogicalPlan query, ExpressionId id) {
super(location, Collections.emptyList());
this.query = query;
this.id = (id == null ? ExpressionIdGenerator.newId() : id);
this.id = id == null ? new ExpressionId() : id;
}
public LogicalPlan query() {

View File

@ -15,7 +15,7 @@ import java.util.List;
abstract class UnresolvedNamedExpression extends NamedExpression implements Unresolvable {
UnresolvedNamedExpression(Location location, List<Expression> children) {
super(location, "<unresolved>", children, ExpressionIdGenerator.EMPTY);
super(location, "<unresolved>", children, new ExpressionId());
}
@Override

View File

@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression;
import org.elasticsearch.test.ESTestCase;
public class ExpressionIdTests extends ESTestCase {
/**
* Each {@link ExpressionId} should be unique. Technically
* you can roll the {@link AtomicLong} that backs them but
* that is not going to happen within a single query.
*/
public void testUnique() {
assertNotEquals(new ExpressionId(), new ExpressionId());
}
}