phoenix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Eric Lomore (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (PHOENIX-3437) Calcite allows CURRENT VALUE to be called on a sequence which has not yet been used
Date Thu, 03 Nov 2016 21:21:58 GMT

    [ 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)

Mime
View raw message