[ https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15597332#comment-15597332 ]
Kevin Liew edited comment on PHOENIX-476 at 10/22/16 5:30 PM: -------------------------------------------------------------- Hi [~jamestaylor], I made the suggested changes to recreate the create-table statement with the literal value string that we get after compiling the statement. Without a StatementContext, that takes us back to the issue with parsing negative literal numbers at `new SQLParser(column.getExpressionStr()).parseLiteral()`. I tried defining a new parse function without adding new tokens so that other functions won't be affected but the parser throws an exception during the prediction stage. {code} // Get a string, integer, double, date, boolean, or NULL value. // Able to parse negative numbers. any_literal returns [LiteralParseNode ret] : s=STRING_LITERAL { ret = factory.literal(s.getText()); } | n=NUMBER { ret = factory.wholeNumber(n.getText()); } | nn=MINUS DIGIT+ { ret = factory.wholeNumber(nn.getText()); } | d=DECIMAL { ret = factory.realNumber(d.getText()); } | nd=MINUS DIGIT+ DOT POSINTEGER { ret = factory.realNumber(nd.getText()); } | dbl=DOUBLE { ret = factory.literal(Double.valueOf(dbl.getText())); } | ndbl='.' POSINTEGER Exponent | MINUS DIGIT+ DOT Exponent | MINUS DIGIT+ (DOT (POSINTEGER (Exponent)?)? | Exponent) { ret = factory.literal(Double.valueOf(ndbl.getText())); } | NULL {ret = factory.literal(null);} | TRUE {ret = factory.literal(Boolean.TRUE);} | FALSE {ret = factory.literal(Boolean.FALSE);} | dt=identifier t=STRING_LITERAL { try { ret = factory.literal(t.getText(), dt); } catch (SQLException e) { throw new RuntimeException(e); } } ; {code} was (Author: kliew): Hi [~jamestaylor], I made the suggested changes to recreate the create-table statement with the literal value string that we get after compiling the statement. Without a StatementContext, that takes us back to the issue with parsing negative literals at `new SQLParser(column.getExpressionStr()).parseLiteral()`. I tried defining a new parse function without adding new tokens so that other functions won't be affected but the parser throws an exception during the prediction stage. {code} // Get a string, integer, double, date, boolean, or NULL value. // Able to parse negative numbers. any_literal returns [LiteralParseNode ret] : s=STRING_LITERAL { ret = factory.literal(s.getText()); } | n=NUMBER { ret = factory.wholeNumber(n.getText()); } | nn=MINUS DIGIT+ { ret = factory.wholeNumber(nn.getText()); } | d=DECIMAL { ret = factory.realNumber(d.getText()); } | nd=MINUS DIGIT+ DOT POSINTEGER { ret = factory.realNumber(nd.getText()); } | dbl=DOUBLE { ret = factory.literal(Double.valueOf(dbl.getText())); } | ndbl='.' POSINTEGER Exponent | MINUS DIGIT+ DOT Exponent | MINUS DIGIT+ (DOT (POSINTEGER (Exponent)?)? | Exponent) { ret = factory.literal(Double.valueOf(ndbl.getText())); } | NULL {ret = factory.literal(null);} | TRUE {ret = factory.literal(Boolean.TRUE);} | FALSE {ret = factory.literal(Boolean.FALSE);} | dt=identifier t=STRING_LITERAL { try { ret = factory.literal(t.getText(), dt); } catch (SQLException e) { throw new RuntimeException(e); } } ; {code} > Support declaration of DEFAULT in CREATE statement > -------------------------------------------------- > > Key: PHOENIX-476 > URL: https://issues.apache.org/jira/browse/PHOENIX-476 > Project: Phoenix > Issue Type: Task > Affects Versions: 3.0-Release > Reporter: James Taylor > Assignee: Kevin Liew > Labels: enhancement > Fix For: 4.9.0 > > Attachments: PHOENIX-476.2.patch, PHOENIX-476.3.patch, > PHOENIX-476.4.patch, PHOENIX-476.5.patch, PHOENIX-476.6.patch, > PHOENIX-476.7.patch, PHOENIX-476.patch > > > Support the declaration of a default value in the CREATE TABLE/VIEW statement > like this: > CREATE TABLE Persons ( > Pid int NOT NULL PRIMARY KEY, > LastName varchar(255) NOT NULL, > FirstName varchar(255), > Address varchar(255), > City varchar(255) DEFAULT 'Sandnes' > ) > To implement this, we'd need to: > 1. add a new DEFAULT_VALUE key value column in SYSTEM.TABLE and pass through > the value when the table is created (in MetaDataClient). > 2. always set NULLABLE to ResultSetMetaData.columnNoNulls if a default value > is present, since the column will never be null. > 3. add a getDefaultValue() accessor in PColumn > 4. for a row key column, during UPSERT use the default value if no value was > specified for that column. This could be done in the PTableImpl.newKey method. > 5. for a key value column with a default value, we can get away without > incurring any storage cost. Although a little bit of extra effort than if we > persisted the default value on an UPSERT for key value columns, this approach > has the benefit of not incurring any storage cost for a default value. > * serialize any default value into KeyValueColumnExpression > * in the evaluate method of KeyValueColumnExpression, conditionally use > the default value if the column value is not present. If doing partial > evaluation, you should not yet return the default value, as we may not have > encountered the the KeyValue for the column yet (since a filter evaluates > each time it sees each KeyValue, and there may be more than one KeyValue > referenced in the expression). Partial evaluation is determined by calling > Tuple.isImmutable(), where false means it is NOT doing partial evaluation, > while true means it is. > * modify EvaluateOnCompletionVisitor by adding a visitor method for > RowKeyColumnExpression and KeyValueColumnExpression to set > evaluateOnCompletion to true if they have a default value specified. This > will cause filter evaluation to execute one final time after all KeyValues > for a row have been seen, since it's at this time we know we should use the > default value. -- This message was sent by Atlassian JIRA (v6.3.4#6332)