[
https://issues.apache.org/jira/browse/PHOENIX-3437?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15634329#comment-15634329
]
Eric Lomore commented on PHOENIX-3437:
--------------------------------------
For reference, the logic we are using is:
{code}
private PhoenixSequence resolveSequence(String name) {
try {
SequenceManager manager = new SequenceManager(statement);
manager.newSequenceReference(pc.getTenantId(),
TableName.createNormalized(schemaName, name) , null,
SequenceValueParseNode.Op.NEXT_VALUE);
manager.validateSequences(Sequence.ValueOp.VALIDATE_SEQUENCE);
} catch (SQLException e){
return null;
}
return new PhoenixSequence(schemaName, name, pc);
}{code}
But, I don't see any logic that notes the difference between
Sequence.ValueOp.VALIDIATE_SEQUENCE and the others.
{code}
@Override
public void validateSequences(List<SequenceAllocation> sequenceAllocations,
long timestamp, long[] values, SQLException[] exceptions, Sequence.ValueOp
action) throws SQLException {
incrementSequenceValues(sequenceAllocations, timestamp, values,
exceptions, action);
}
{code}
{code}
private void incrementSequenceValues(List<SequenceAllocation>
sequenceAllocations, long timestamp, long[] values, SQLException[] exceptions,
Sequence.ValueOp op) throws SQLException {
List<Sequence> sequences =
Lists.newArrayListWithExpectedSize(sequenceAllocations.size());
for (SequenceAllocation sequenceAllocation : sequenceAllocations) {
SequenceKey key = sequenceAllocation.getSequenceKey();
Sequence newSequences = new Sequence(key);
Sequence sequence = sequenceMap.putIfAbsent(key, newSequences);
{code}
In other words, in the validate process a sequence is added to the sequenceMap
regardless of the Op specified.
If we are to use this API think a change might be needed to reflect this
difference.
What are your thoughts, [~jamestaylor]?
> Calcite allows CURRENT VALUE to be called on a sequence which has not yet
> been used
> -----------------------------------------------------------------------------------
>
> Key: PHOENIX-3437
> URL: https://issues.apache.org/jira/browse/PHOENIX-3437
> Project: Phoenix
> Issue Type: Sub-task
> Reporter: Eric Lomore
> Assignee: Eric Lomore
>
> Calcite currently returns 0 for a sequence that has CURRENT VALUE called on
> it before NEXT VALUE is ever called.
> To demonstrate, this sample integration test passes.
> {code}
> connection.createStatement().execute("CREATE SEQUENCE IF NOT EXISTS
> seq0 START WITH 1 INCREMENT BY 1");
> start(false, 1000f).sql("select CURRENT VALUE FOR seq0, c0 from
> (values (1), (1)) as t(c0)")
> .explainIs("PhoenixToEnumerableConverter\n" +
> "
> PhoenixClientProject(EXPR$0=[CURRENT_VALUE('\"SEQ0\"')], C0=[$0])\n" +
> " PhoenixValues(tuples=[[{ 1 }, { 1 }]])\n")
> .resultIs(0, new Object[][]{
> {0L, 1},
> {0L, 1}})
> .close();
> {code}
> But Phoenix's intended behaviour is for this to throw an exception.
> {{SequenceIT.java}}
> {code}
> @Test
> public void testCurrentValueFor() throws Exception {
> ResultSet rs;
> nextConnection();
> conn.createStatement().execute("CREATE SEQUENCE used.nowhere START
> WITH 2 INCREMENT BY 4");
> nextConnection();
> try {
> rs = conn.createStatement().executeQuery("SELECT CURRENT VALUE
> FOR used.nowhere FROM SYSTEM.\"SEQUENCE\"");
> rs.next();
> fail();
> } catch (SQLException e) {
>
> assertEquals(SQLExceptionCode.CANNOT_CALL_CURRENT_BEFORE_NEXT_VALUE.getErrorCode(),
> e.getErrorCode());
> assertTrue(e.getNextException()==null);
> }
>
> rs = conn.createStatement().executeQuery("SELECT NEXT VALUE FOR
> used.nowhere FROM SYSTEM.\"SEQUENCE\"");
> assertTrue(rs.next());
> assertEquals(2, rs.getInt(1));
> rs = conn.createStatement().executeQuery("SELECT CURRENT VALUE FOR
> used.nowhere FROM SYSTEM.\"SEQUENCE\"");
> assertTrue(rs.next());
> assertEquals(2, rs.getInt(1));
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)