[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2017-02-17 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15873022#comment-15873022
 ] 

Kevin Liew edited comment on PHOENIX-476 at 2/18/17 6:59 AM:
-

Hi [~tdsilva], support for sequence expressions is planned for PHOENIX-3425, 
which will likely be picked up again after the Calcite integration.
We do expect this error when parsing sequence values as default expression:
{code:java}
CANNOT_CREATE_DEFAULT(1031, "42Y90", "Cannot create column with a stateful 
default value.")
{code}


was (Author: kliew):
Hi [~tdsilva], support for sequence expressions is planned for PHOENIX-3425.
We do expect this error when parsing sequence values as default expression:
{code:java}
CANNOT_CREATE_DEFAULT(1031, "42Y90", "Cannot create column with a stateful 
default value.")
{code}

> Support declaration of DEFAULT in CREATE statement
> --
>
> Key: PHOENIX-476
> URL: https://issues.apache.org/jira/browse/PHOENIX-476
> Project: Phoenix
>  Issue Type: New Feature
>Affects Versions: 3.0-Release
>Reporter: James Taylor
>Assignee: Kevin Liew
> Fix For: 4.9.0
>
> Attachments: PHOENIX-476.10.patch, PHOENIX-476.11.patch, 
> PHOENIX-476.12.patch, 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.8.patch, PHOENIX-476.9.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.15#6346)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-22 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15598651#comment-15598651
 ] 

Kevin Liew edited comment on PHOENIX-476 at 10/22/16 11:08 PM:
---

I got it working. With the recent changes, we access the context again during 
the UPSERT so we can compile arbitrary isConstant expressions. I just needed to 
revert the older changes where we were compiling the expression to a literal in 
CreateTableCompiler and storing the expression string obtained from that. 

For scalar date-time, the expression was untouched. For arrays, it was being 
modified below:
{code:java}
public Expression visitLeave(ArrayConstructorNode node, List 
children) throws SQLException {
...
ArrayConstructorExpression arrayExpression = new 
ArrayConstructorExpression(children, arrayElemDataType, rowKeyOrderOptimizable);
if (ExpressionUtil.isConstant(arrayExpression)) {
for (int i = 0; i < children.size(); i++) {
Expression child = children.get(i);
child.evaluate(null, ptr);
Object value = null;
if (child.getDataType() == null) {
value = arrayElemDataType.toObject(ptr, 
theArrayElemDataType, child.getSortOrder());
} else {
value = arrayElemDataType.toObject(ptr, 
child.getDataType(), child.getSortOrder());
}
elements[i] = LiteralExpression.newConstant(value, 
theArrayElemDataType, child.getDeterminism()).getValue();
}
Object value = 
PArrayDataType.instantiatePhoenixArray(arrayElemDataType, elements);
return LiteralExpression.newConstant(value,
PDataType.fromTypeId(arrayElemDataType.getSqlType() + 
PDataType.ARRAY_TYPE_BASE), null, null, arrayExpression.getSortOrder(), 
Determinism.ALWAYS, rowKeyOrderOptimizable);
}
{code}
It looks that behavior was intended for some other use case but the issue might 
show up again.

Its just testing and cleanup left now.


was (Author: kliew):
I got it working. With the recent changes, we access the context again during 
the UPSERT so we can compile arbitrary isConstant expressions. I just needed to 
revert the older changes where we were compiling the expression to a literal in 
CreateTableCompiler and storing the expression string obtained from that. 

For scalar date-time, the expression was untouched. For arrays, it was being 
modified below:
{code:java}
public Expression visitLeave(ArrayConstructorNode node, List 
children) throws SQLException {
...
ArrayConstructorExpression arrayExpression = new 
ArrayConstructorExpression(children, arrayElemDataType, rowKeyOrderOptimizable);
if (ExpressionUtil.isConstant(arrayExpression)) {
for (int i = 0; i < children.size(); i++) {
Expression child = children.get(i);
child.evaluate(null, ptr);
Object value = null;
if (child.getDataType() == null) {
value = arrayElemDataType.toObject(ptr, 
theArrayElemDataType, child.getSortOrder());
} else {
value = arrayElemDataType.toObject(ptr, 
child.getDataType(), child.getSortOrder());
}
elements[i] = LiteralExpression.newConstant(value, 
theArrayElemDataType, child.getDeterminism()).getValue();
}
Object value = 
PArrayDataType.instantiatePhoenixArray(arrayElemDataType, elements);
return LiteralExpression.newConstant(value,
PDataType.fromTypeId(arrayElemDataType.getSqlType() + 
PDataType.ARRAY_TYPE_BASE), null, null, arrayExpression.getSortOrder(), 
Determinism.ALWAYS, rowKeyOrderOptimizable);
}
{code}

Its just testing and cleanup left now.

> 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.8.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 

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-22 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15598382#comment-15598382
 ] 

Kevin Liew edited comment on PHOENIX-476 at 10/22/16 7:52 PM:
--

We compile the string to an expression in CreateTableCompiler and save that to 
the metastore. For arrays: the date-time is represented as a string (without 
the type specifier) in the new expression string.

When we call `parseExpression` while doing UPSERT, it only sees the string 
without the type information.

{code:java}
ExpressionCompiler compiler = new ExpressionCompiler(context);
ParseNode defaultParseNode = new 
SQLParser(column.getExpressionStr()).parseExpression();
Expression defaultExpression = defaultParseNode.accept(compiler);
{code}

For scalar columns, the type specifier is not removed after compiling an 
Expression (ie. "DATE '1900-10-01 14:03:22.559'").

I don't think it is expected for the type specifier to be removed after 
compiling array values.


was (Author: kliew):
We compile the string to an expression contained in a ColumnDef. For arrays: 
the date-time is represented as a string (without the type specifier) in the 
new expression string.

When we call `parseExpression`, it only sees the string without the type 
information.

{code:java}
ExpressionCompiler compiler = new ExpressionCompiler(context);
ParseNode defaultParseNode = new 
SQLParser(column.getExpressionStr()).parseExpression();
Expression defaultExpression = defaultParseNode.accept(compiler);
{code}

For scalar columns, the type specifier is not removed after compiling an 
Expression (ie. "DATE '1900-10-01 14:03:22.559'").

I don't think it is expected for the type specifier to be removed after 
compiling array values.

> 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.8.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-22 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15598326#comment-15598326
 ] 

Kevin Liew edited comment on PHOENIX-476 at 10/22/16 7:15 PM:
--

The byte coercion fix for data types also fixed byte coercion for arrays. 

Right now I'm running into a problem with default values for date-time types.

"time '1900-10-01 14:03:22.559'" worked for non array types.

I tried a few different variations of:
{code:sql}
tim TIME[5] DEFAULT ARRAY[time '1900-10-01 14:03:22.559', time '1901-10-01 
14:03:22.559']
{code}

{code}

org.apache.phoenix.schema.TypeMismatchException: ERROR 203 (22005): Type 
mismatch. ERROR 203 (22005): Type mismatch. ERROR 203 (22005): Type mismatch. 
ERROR 203 (22005): Type mismatch. VARCHAR cannot be coerced to TIME

at 
org.apache.phoenix.exception.SQLExceptionCode$1.newException(SQLExceptionCode.java:74)
at 
org.apache.phoenix.exception.SQLExceptionInfo.buildException(SQLExceptionInfo.java:145)
at 
org.apache.phoenix.util.ServerUtil.parseRemoteException(ServerUtil.java:129)
at 
org.apache.phoenix.util.ServerUtil.parseServerExceptionOrNull(ServerUtil.java:118)
at 
org.apache.phoenix.util.ServerUtil.parseServerException(ServerUtil.java:107)
at 
org.apache.phoenix.iterate.BaseResultIterators.getIterators(BaseResultIterators.java:751)
at 
org.apache.phoenix.iterate.BaseResultIterators.getIterators(BaseResultIterators.java:695)
at 
org.apache.phoenix.iterate.ConcatResultIterator.getIterators(ConcatResultIterator.java:50)
at 
org.apache.phoenix.iterate.ConcatResultIterator.currentIterator(ConcatResultIterator.java:97)
at 
org.apache.phoenix.iterate.ConcatResultIterator.next(ConcatResultIterator.java:117)
at 
org.apache.phoenix.jdbc.PhoenixResultSet.next(PhoenixResultSet.java:778)
at 
org.apache.phoenix.end2end.DefaultColumnValueIT.testDefaultArrays(DefaultColumnValueIT.java:732)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at 
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at 
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at 
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at 
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at 
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at 
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at 
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at 
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at 
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at 
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at 
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at 
com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at 
com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
{code}

I'll try alternate syntax, but was the above syntactically correct?

I also tried the TO_TIME function.


was (Author: kliew):
The byte coercion fix for data types also fixed byte coercion for arrays. 

Right now I'm running into a problem with def

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-22 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15598280#comment-15598280
 ] 

Kevin Liew edited comment on PHOENIX-476 at 10/22/16 6:36 PM:
--

Thanks James, that works. I'll get started on array support and further 
revision and testing .


was (Author: kliew):
Thanks James, that works. 

> 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.8.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-22 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15598242#comment-15598242
 ] 

Kevin Liew edited comment on PHOENIX-476 at 10/22/16 6:10 PM:
--

Oops, sorry I had to reset my environment so the patch is messy due to IDE 
changes. I cleaned up and reattached the patch. 


was (Author: kliew):
Oops, sorry I had to reset my environment so the patch is messy due to IDE 
changes. I will clean up the patch and attach again. 

> 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.8.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-22 Thread James Taylor (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15598225#comment-15598225
 ] 

James Taylor edited comment on PHOENIX-476 at 10/22/16 5:53 PM:


No parser changes are required:
- In CreateTableCompiler, when you compile the defaultExpression, you'll end up 
with a LiteralExpression (i.e. DEFAULT -2 + 7 would be turned into a 
LiteralExpression of 5). Create a new CreateTableStatement copy constructor 
that passes in a createTableStatement and an expressionStr. Use this to create 
a new CreateTableStatement using defaultExpression.toString() to form the 
literal expression string which you'll pass through to the MetaDataClient to 
guarantee that the default expression is always a literal.
- By evaluating the default expression at CREATE TABLE time, and storing the 
evaluated expression string value, you'll know you have literal. When reading 
and parsing the default value back in PTableImpl, you can assume it's already a 
literal and parse it as you were doing in your previous patch:
{code}
+LiteralParseNode defaultParseNode = new 
SQLParser(column.getExpressionStr()).parseLiteral();
+LiteralExpression defaultLiteral = 
LiteralExpression.newConstant(defaultParseNode.getValue(), 
column.getDataType(), column.getMaxLength(), column.getScale(), 
column.getSortOrder(), Determinism.ALWAYS);
+ImmutableBytesWritable valuePtr = new 
ImmutableBytesWritable();
+defaultLiteral.evaluate(null, valuePtr);
+byteValue = 
ByteUtil.copyKeyBytesIfNecessary(valuePtr);
{code}


was (Author: jamestaylor):
No parser changes are required:
-In CreateTableCompiler, when you compile the defaultExpression, you'll end up 
with a LiteralExpression (i.e. DEFAULT -2 + 7 would be turned into a 
LiteralExpression of 5). Create a new CreateTableStatement copy constructor 
that passes in a createTableStatement and an expressionStr. Use this to create 
a new CreateTableStatement using defaultExpression.toString() to form the 
literal expression string which you'll pass through to the MetaDataClient to 
guarantee that the default expression is always a literal.
- By evaluating the default expression at CREATE TABLE time, and storing the 
evaluated expression string value, you'll know you have literal. When reading 
and parsing the default value back in PTableImpl, you can assume it's already a 
literal and parse it as you were doing in your previous patch:
{code}
+LiteralParseNode defaultParseNode = new 
SQLParser(column.getExpressionStr()).parseLiteral();
+LiteralExpression defaultLiteral = 
LiteralExpression.newConstant(defaultParseNode.getValue(), 
column.getDataType(), column.getMaxLength(), column.getScale(), 
column.getSortOrder(), Determinism.ALWAYS);
+ImmutableBytesWritable valuePtr = new 
ImmutableBytesWritable();
+defaultLiteral.evaluate(null, valuePtr);
+byteValue = 
ByteUtil.copyKeyBytesIfNecessary(valuePtr);
{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 benef

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-22 Thread Kevin Liew (JIRA)

[ 
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 

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-22 Thread Kevin Liew (JIRA)

[ 
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:17 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 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}


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.

{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 

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-10-09 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15559451#comment-15559451
 ] 

Kevin Liew edited comment on PHOENIX-476 at 10/9/16 7:03 AM:
-

I attached a patch with additional test coverage and all test cases passing.
Expressions are now cached outside of PColumn and ColumnDef. The driver sends 
the default value expression as part of the projector scan and the coprocessors 
reply with the result sets with default values substituted in (previously I was 
trying to get the driver to differentiate between nulls and default values at 
the client side to reduce the resultset size, but it was causing issues).
Let me know your feedback.


was (Author: kliew):
I attached a patch with additional test coverage and all test cases passing.
Expressions are now cached outside of PColumn and ColumnDef. The driver sends 
the default value expression as part of the projector scan and the coprocessors 
reply with the result sets with default values substituted in (previously I was 
trying to get the driver to differentiate between nulls and default values at 
the client side, which was causing issues).
Let me know your feedback.

> 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
> Attachments: PHOENIX-476.2.patch, PHOENIX-476.3.patch, 
> PHOENIX-476.4.patch, PHOENIX-476.5.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-27 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15527244#comment-15527244
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/27/16 8:08 PM:
-

Thanks James, will do. I didn’t have the right context to understand the 
interactions between the coprocessor and driver; I was too focused on the 
individual components but I’m starting to see how it fits together.


was (Author: kliew):
Thanks James, will do. I didn’t have the right context; I was too focused on 
the individual parts but I’m starting to see how it fits together.

> 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
> Attachments: PHOENIX-476.2.patch, PHOENIX-476.3.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-26 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15524834#comment-15524834
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/27/16 2:41 AM:
-

I did take a look at `PRowImpl.setValue` but that only determines how rows are 
serialized to disk. `KeyValueSchema.toBytes` determines how rows are serialized 
from the coprocessor to be sent to the driver. 

{code:java}
for (int j = 0; j < field.getCount(); j++) {
if (expressions[index].evaluate(tuple, ptr) && ptr.getLength() > 0) { // 
Skip null values
if (index >= minNullableIndex) {
valueSet.set(index - minNullableIndex);
}
if (!type.isFixedWidth()) {
b = ensureSize(b, offset, offset + 
getVarLengthBytes(ptr.getLength()));
offset = writeVarLengthField(ptr, b, offset);
} else {
int nBytes = ptr.getLength();
b = ensureSize(b, offset, offset + nBytes);
System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, nBytes);
offset += nBytes;
}
}
index++;
}
{code}

In the code above (for `KeyValueSchema.toBytes`), regardless of whether we 
store the null value on disk, nulls are not set in the value bitmask. _The 
driver receives only non-null values and a value bitmask from the coprocessor_, 
using these to evaluate the Expression tree.

We could decide to store nulls but not default values on disk, which is what I 
think you were suggesting. Then we could differentiate nulls from default 
values and set default values in the value bitmask so that the driver will not 
see them as null values. 
But the driver also uses the value bitmask to determine the offset used to 
deserialize each cell, and now the driver will not be able to differentiate 
between non-null values that were serialized (and produce additional offset) 
and default values that were not serialized (and throws an exception because 
the expected byte array size is smaller than expected).

The previous test cases were only passing before due to a quirk in the 
`KeyValueSchema.next` -> `Expression.evaluate` logic where non-trailing nulls 
evaluate false -> true while trailing nulls evaluate null -> false.


was (Author: kliew):
I did take a look at `PRowImpl.setValue` but that only determines how rows are 
serialized to disk. `KeyValueSchema.toBytes` determines how rows are serialized 
from the coprocessor to be sent to the driver. 

{code:java}
for (int j = 0; j < field.getCount(); j++) {
if (expressions[index].evaluate(tuple, ptr) && ptr.getLength() 
> 0) { // Skip null values
if (index >= minNullableIndex) {
valueSet.set(index - minNullableIndex);
}
if (!type.isFixedWidth()) {
b = ensureSize(b, offset, offset + 
getVarLengthBytes(ptr.getLength()));
offset = writeVarLengthField(ptr, b, offset);
} else {
int nBytes = ptr.getLength();
b = ensureSize(b, offset, offset + nBytes);
System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, 
nBytes);
offset += nBytes;
}
}
index++;
}
{code}

In the code above (for `KeyValueSchema.toBytes`), regardless of whether we 
store the null value on disk, nulls are not set in the value bitmask. _The 
driver receives only non-null values and a value bitmask from the coprocessor_, 
using these to evaluate the Expression tree.

We could decide to store nulls but not default values on disk, which is what I 
think you were suggesting. Then we could differentiate nulls from default 
values and set default values in the value bitmask so that the driver will not 
see them as null values. 
But the driver also uses the value bitmask to determine the offset used to 
deserialize each cell, and now the driver will not be able to differentiate 
between non-null values that were serialized (and produce additional offset) 
and default values that were not serialized (and throws an exception because 
the expected byte array size is smaller than expected).

The previous test cases were only passing before due to a quirk in the 
`KeyValueSchema.next` -> `Expression.evaluate` logic where non-trailing nulls 
evaluate false -> true while trailing nulls evaluate null -> false.

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

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-26 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15524834#comment-15524834
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/27/16 2:40 AM:
-

I did take a look at `PRowImpl.setValue` but that only determines how rows are 
serialized to disk. `KeyValueSchema.toBytes` determines how rows are serialized 
from the coprocessor to be sent to the driver. 

{code:java}
for (int j = 0; j < field.getCount(); j++) {
if (expressions[index].evaluate(tuple, ptr) && ptr.getLength() 
> 0) { // Skip null values
if (index >= minNullableIndex) {
valueSet.set(index - minNullableIndex);
}
if (!type.isFixedWidth()) {
b = ensureSize(b, offset, offset + 
getVarLengthBytes(ptr.getLength()));
offset = writeVarLengthField(ptr, b, offset);
} else {
int nBytes = ptr.getLength();
b = ensureSize(b, offset, offset + nBytes);
System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, 
nBytes);
offset += nBytes;
}
}
index++;
}
{code}

In the code above (for `KeyValueSchema.toBytes`), regardless of whether we 
store the null value on disk, nulls are not set in the value bitmask. _The 
driver receives only non-null values and a value bitmask from the coprocessor_, 
using these to evaluate the Expression tree.

We could decide to store nulls but not default values on disk, which is what I 
think you were suggesting. Then we could differentiate nulls from default 
values and set default values in the value bitmask so that the driver will not 
see them as null values. 
But the driver also uses the value bitmask to determine the offset used to 
deserialize each cell, and now the driver will not be able to differentiate 
between non-null values that were serialized (and produce additional offset) 
and default values that were not serialized (and throws an exception because 
the expected byte array size is smaller than expected).

The previous test cases were only passing before due to a quirk in the 
`KeyValueSchema.next` -> `Expression.evaluate` logic where non-trailing nulls 
evaluate false -> true while trailing nulls evaluate null -> false.


was (Author: kliew):
I did take a look at `PRowImpl.setValue` but that only determines how rows are 
serialized to disk. `KeyValueSchema.toBytes` determines how rows are serialized 
from the coprocessor to be sent to the driver. 

{code:java}
if (expressions[index].evaluate(tuple, ptr) && ptr.getLength() > 0) { // Skip 
null values
if (index >= minNullableIndex) {
valueSet.set(index - minNullableIndex);
}
if (!type.isFixedWidth()) {
b = ensureSize(b, offset, offset + getVarLengthBytes(ptr.getLength()));
offset = writeVarLengthField(ptr, b, offset);
} else {
int nBytes = ptr.getLength();
b = ensureSize(b, offset, offset + nBytes);
System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, nBytes);
offset += nBytes;
}
}
{code}

In the code above (for `KeyValueSchema.toBytes`), regardless of whether we 
store the null value on disk, nulls are not set in the value bitmask. _The 
driver receives only non-null values and a value bitmask from the coprocessor_, 
using these to evaluate the Expression tree.

We could decide to store nulls but not default values on disk, which is what I 
think you were suggesting. Then we could differentiate nulls from default 
values and set default values in the value bitmask so that the driver will not 
see them as null values. 
But the driver also uses the value bitmask to determine the offset used to 
deserialize each cell, and now the driver will not be able to differentiate 
between non-null values that were serialized (and produce additional offset) 
and default values that were not serialized (and throws an exception because 
the expected byte array size is smaller than expected).

The previous test cases were only passing before due to a quirk in the 
`KeyValueSchema.next` -> `Expression.evaluate` logic where non-trailing nulls 
evaluate false -> true while trailing nulls evaluate null -> false.

> 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
> Attachments: PHOENIX-476.2.patch, PHOENIX-476.3.patch, 
> PHOENIX-476.patch
>
>
> Support the declaration of a def

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-26 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15524834#comment-15524834
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/27/16 2:38 AM:
-

I did take a look at `PRowImpl.setValue` but that only determines how rows are 
serialized to disk. `KeyValueSchema.toBytes` determines how rows are serialized 
from the coprocessor to be sent to the driver. 

{code:java}
if (expressions[index].evaluate(tuple, ptr) && ptr.getLength() > 0) { // Skip 
null values
if (index >= minNullableIndex) {
valueSet.set(index - minNullableIndex);
}
if (!type.isFixedWidth()) {
b = ensureSize(b, offset, offset + getVarLengthBytes(ptr.getLength()));
offset = writeVarLengthField(ptr, b, offset);
} else {
int nBytes = ptr.getLength();
b = ensureSize(b, offset, offset + nBytes);
System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, nBytes);
offset += nBytes;
}
}
{code}

In the code above (for `KeyValueSchema.toBytes`), regardless of whether we 
store the null value on disk, nulls are not set in the value bitmask. _The 
driver receives only non-null values and a value bitmask from the coprocessor_, 
using these to evaluate the Expression tree.

We could decide to store nulls but not default values on disk, which is what I 
think you were suggesting. Then we could differentiate nulls from default 
values and set default values in the value bitmask so that the driver will not 
see them as null values. 
But the driver also uses the value bitmask to determine the offset used to 
deserialize each cell, and now the driver will not be able to differentiate 
between non-null values that were serialized (and produce additional offset) 
and default values that were not serialized (and throws an exception because 
the expected byte array size is smaller than expected).

The previous test cases were only passing before due to a quirk in the 
`KeyValueSchema.next` -> `Expression.evaluate` logic where non-trailing nulls 
evaluate false -> true while trailing nulls evaluate null -> false.


was (Author: kliew):
I did take a look at `PRowImpl.setValue` but that only determines how rows are 
serialized to disk. `KeyValueSchema.toBytes` determines how rows are serialized 
from the coprocessor to be sent to the driver. 

{code:java}
if (expressions[index].evaluate(tuple, ptr) && ptr.getLength() > 0) { // Skip 
null values
if (index >= minNullableIndex) {
valueSet.set(index - minNullableIndex);
}
if (!type.isFixedWidth()) {
b = ensureSize(b, offset, offset + getVarLengthBytes(ptr.getLength()));
offset = writeVarLengthField(ptr, b, offset);
} else {
int nBytes = ptr.getLength();
b = ensureSize(b, offset, offset + nBytes);
System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, nBytes);
offset += nBytes;
}
}
{code}

In the code above (for `KeyValueSchema.toBytes`), regardless of whether we 
store the null value on disk, nulls are not set in the value bitmask. _The 
driver receives only non-null values and a value bitmask from the coprocessor_, 
using these evaluate the Expression tree.

We could decide to store nulls but not default values on disk, which is what I 
think you were suggesting. Then we could differentiate nulls from default 
values and set default values in the value bitmask so that the driver will not 
see them as null values. 
But the driver also uses the value bitmask to determine the offset used to 
deserialize each cell, and now the driver will not be able to differentiate 
between non-null values that were serialized (and produce additional offset) 
and default values that were not serialized (and throws an exception because 
the expected byte array size is smaller than expected).

The previous test cases were only passing before due to a quirk in the 
`KeyValueSchema.next` -> `Expression.evaluate` logic where non-trailing nulls 
evaluate false -> true while trailing nulls evaluate null -> false.

> 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
> Attachments: PHOENIX-476.2.patch, PHOENIX-476.3.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, w

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-26 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15524834#comment-15524834
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/27/16 2:38 AM:
-

I did take a look at `PRowImpl.setValue` but that only determines how rows are 
serialized to disk. `KeyValueSchema.toBytes` determines how rows are serialized 
from the coprocessor to be sent to the driver. 

{code:java}
if (expressions[index].evaluate(tuple, ptr) && ptr.getLength() > 0) { // Skip 
null values
if (index >= minNullableIndex) {
valueSet.set(index - minNullableIndex);
}
if (!type.isFixedWidth()) {
b = ensureSize(b, offset, offset + getVarLengthBytes(ptr.getLength()));
offset = writeVarLengthField(ptr, b, offset);
} else {
int nBytes = ptr.getLength();
b = ensureSize(b, offset, offset + nBytes);
System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, nBytes);
offset += nBytes;
}
}
{code}

In the code above (for `KeyValueSchema.toBytes`), regardless of whether we 
store the null value on disk, nulls are not set in the value bitmask. _The 
driver receives only non-null values and a value bitmask from the coprocessor_, 
using these evaluate the Expression tree.

We could decide to store nulls but not default values on disk, which is what I 
think you were suggesting. Then we could differentiate nulls from default 
values and set default values in the value bitmask so that the driver will not 
see them as null values. 
But the driver also uses the value bitmask to determine the offset used to 
deserialize each cell, and now the driver will not be able to differentiate 
between non-null values that were serialized (and produce additional offset) 
and default values that were not serialized (and throws an exception because 
the expected byte array size is smaller than expected).

The previous test cases were only passing before due to a quirk in the 
`KeyValueSchema.next` -> `Expression.evaluate` logic where non-trailing nulls 
evaluate false -> true while trailing nulls evaluate null -> false.


was (Author: kliew):
I did take a look at `PRowImpl.setValue` but that only determines how rows are 
serialized to disk. `KeyValueSchema.toBytes` determines how rows are serialized 
from the coprocessor to be sent to the driver. 

{code:java}
if (expressions[index].evaluate(tuple, ptr) && ptr.getLength() > 0) { // Skip 
null values
if (index >= minNullableIndex) {
valueSet.set(index - minNullableIndex);
}
if (!type.isFixedWidth()) {
b = ensureSize(b, offset, offset + getVarLengthBytes(ptr.getLength()));
offset = writeVarLengthField(ptr, b, offset);
} else {
int nBytes = ptr.getLength();
b = ensureSize(b, offset, offset + nBytes);
System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, nBytes);
offset += nBytes;
}
}
{code}

In the code above (for `KeyValueSchema.toBytes`), regardless of whether we 
store the null value on disk, nulls are not set in the value bitmask. The 
driver receives only non-null values and a value bitmask from the coprocessor.

We could decide to store nulls but not default values on disk, which is what I 
think you were suggesting. Then we could differentiate nulls from default 
values and set default values in the value bitmask so that the driver will not 
see them as null values. 
But the driver also uses the value bitmask to determine the offset used to 
deserialize each cell, and now the driver will not be able to differentiate 
between non-null values that were serialized (and produce additional offset) 
and default values that were not serialized (and throws an exception because 
the expected byte array size is smaller than expected).

The previous test cases were only passing before due to a quirk in the 
`KeyValueSchema.next` -> `Expression.evaluate` logic where non-trailing nulls 
evaluate false -> true while trailing nulls evaluate null -> false.

> 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
> Attachments: PHOENIX-476.2.patch, PHOENIX-476.3.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 va

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-26 Thread James Taylor (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15523344#comment-15523344
 ] 

James Taylor edited comment on PHOENIX-476 at 9/26/16 3:15 PM:
---

bq. I think that given the constraints that we have now, we might need to 
serialize another bitmask indicating default values. Does that sound like a 
good solution?
There's no need to make any changes to this because the DefaultValueExpression 
would have already been executed and correctly determined the correct value 
(whether null or the default value). The ProjectedColumnExpression is evaluated 
on the client side, *after* the DefaultValueExpression(KeyValueExpression) 
would already have been evaluated, so if it's null at that point, it really 
should stay null.

I think the remaining work is here[1]. Have you tried this yet, [~kliew] to see 
if there are any more issues once these are done?

[1] 
https://issues.apache.org/jira/browse/PHOENIX-476?focusedCommentId=15507199&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-15507199


was (Author: jamestaylor):
bq. I think that given the constraints that we have now, we might need to 
serialize another bitmask indicating default values.
Does that sound like a good solution?
There's no need to make any changes to this because the DefaultValueExpression 
would have already been executed and correctly determined the correct value 
(whether null or the default value). The ProjectedColumnExpression is evaluated 
on the client side, *after* the DefaultValueExpression(KeyValueExpression) 
would already have been evaluated, so if it's null at that point, it really 
should stay null.

I think the remaining work is here[1]. Have you tried this yet, [~kliew] to see 
if there are any more issues once these are done?

[1] 
https://issues.apache.org/jira/browse/PHOENIX-476?focusedCommentId=15507199&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-15507199

> 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
> Attachments: PHOENIX-476.2.patch, PHOENIX-476.3.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-25 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=1551#comment-1551
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/26/16 6:43 AM:
-

Thanks for the feedback guys. I investigated some more and I think I understand 
the issue more clearly now.

We’ve set (in MetadataClient) tables with default value columns to store nulls 
in HBase and we can detect whether a cell is null or default in 
`PRowImpl.setValue`. Next, we’d need to communicate that from the coprocessor 
to the driver but the rows serialized on the coprocessors contain only the 
non-null values followed by a bitmask indicating set/null values. Currently 
both nulls and default values are indicated as nulls in the bitmask.

We can’t change the value bitmask to indicate that default values are set and 
not null, because that would affect the size of the expected bytes and the 
offsets used for deserialization at the driver. 

I think that given the constraints that we have now, we might need to serialize 
another bitmask indicating default values. 
Does that sound like a good solution?
I think we’d run into the same constraints after migrating to Calcite because 
the root of the issue lies in the communication between the coprocessor and the 
driver.

Regarding `isConstant`: I think we can borrow the term ‘pure’ from functional 
programmers :). The current implementation for `isConstant` describes the 
criteria for a pure expression.

Thanks for pointing out the parens [~julianhyde]. I’ll remove them so that the 
tests will pass after migrating to Calcite.


was (Author: kliew):
Thanks for the feedback guys. I investigated some more and I think I understand 
the issue more clearly now.

We’ve set (in MetadataClient) tables with default value columns to store nulls 
in HBase and we can detect whether a cell is null or default in 
`PRowImpl.setValue`. Next, we’d need to communicate that from the coprocessor 
to the driver but the rows serialized on the coprocessors contain only the 
non-null values followed by a bitmask indicating set/null values. Currently 
both nulls and default values are indicated as nulls in the bitmask.

We can’t change the value bitmask to indicate that default values are set and 
not null, because that would affect the size of the expected bytes and the 
offsets used for deserialization at the driver. 

I think that given the constraints that we have now, we might need to serialize 
another bitmask indicating default values. 
Does that sound like a good solution?
I think we’d run into the same constraints after migrating to Calcite because 
the root of the issue lies in the communication between the coprocessor and the 
driver.

Regarding `isConstant`: I think we can borrow the term ‘pure’ from functional 
programmers :). The current implementation for `isConstant` describes the 
criteria for a pure expression.

Thanks for pointing out the parens [~julianhyde]. I’ll removed them so that the 
tests will pass after migrating to Calcite.

> 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
> Attachments: PHOENIX-476.2.patch, PHOENIX-476.3.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 doin

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-20 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15505920#comment-15505920
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/20/16 7:51 AM:
-

I attached a new patch implementing default values for both primary and 
row-value columns. 

There are a few issues though.

* After compiling a default value ParseNode into an Expression, it becomes a 
LiteralExpression. For `CURRENT_DATE()`, the ParseNode is stateless and the 
compiled `Expression.isConstant` is true so we aren’t able to throw an 
exception. Is there a existing expression compiler or a flag that will not 
convert the default value ParseNode to LiteralExpression?
Setting `requiresFinalEvaluation` did not change the result.

* DefaultValueExpression wraps a ProjectedColumnExpression in 
ExpressionCompiler. 
I modified `ProjectedColumnExpression.evaluate`  so that it returns true if the 
cell contains a null value.
But `KeyValueSchema.next` returns `null` for trailing nulls in a row so 
`ProjectedColumnExpression.evaluate` cannot differentiate between a trailing 
null and trailing default value.
If we change the return value contract of `KeyValueSchema.next`, it causes 
failures in other test cases (ie. SortMergeIT).
I’m not familiar with the serialization scheme for rows returned by the region 
servers, but I suspect that trailing nulls are trimmed, which might be why 
`KeyValueSchema.next` does not account for trailing nulls.
To fix this, we might have to provide an option to serialize trailing nulls 
from region servers, change the return contract of `KeyValueSchema.next`, and 
modify the affected components.

The following test case (which isn't in the patch) fails due to a trailing 
default value that is overwritten by a null value:
{code:java}

@Test
public void testCreateTableTrailingNullOverwritingDefault() throws 
Exception {
String table = generateRandomString();
String ddl = "CREATE TABLE " + table + " (" +
"pk INTEGER PRIMARY KEY, " +
"def INTEGER DEFAULT 1 + 9)";

long ts = nextTimestamp();
Properties props = new Properties();
props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.createStatement().execute(ddl);

String dml = "UPSERT INTO " + table + " VALUES (1, null)";
conn.createStatement().execute(dml);
conn.commit();

props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 
10));
conn = DriverManager.getConnection(getUrl(), props);

ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + 
table + " WHERE pk = 1");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals(0, rs.getInt(2));
assertTrue(rs.wasNull());
assertFalse(rs.next());
}
{code}


was (Author: kliew):
I attached a new patch implementing default values for both primary and 
row-value columns. 

There are a few issues though.

* After compiling a default value ParseNode into an Expression, it becomes a 
LiteralExpression. For `CURRENT_DATE()`, the ParseNode is stateless and the 
compiled `Expression.isConstant` is true so we aren’t able to throw an 
exception. Is there a existing expression compiler or a flag that will not 
convert the default value ParseNode to LiteralExpression?
Setting `requiresFinalEvaluation` did not change the result.

* DefaultValueExpression wraps a ProjectedColumnExpression in 
ExpressionCompiler. 
I modified `ProjectedColumnExpression.evaluate`  so that it returns true if the 
cell contains a null value.
But `KeyValueSchema.next` returns `null` for trailing nulls in a row so 
`ProjectedColumnExpression.evaluate` cannot differentiate between a trailing 
null and trailing default value.
If we change the return value contract of `KeyValueSchema.next`, it causes 
failures in other test cases (ie. SortMergeIT).
I’m not familiar with the serialization scheme for rows returned by the region 
servers, but I suspect that trailing nulls are trimmed, which might be why 
`KeyValueSchema.next` does not account for trailing nulls.

The following test case (which isn't in the patch) fails due to a trailing 
default value that is overwritten by a null value:
{code:java}

@Test
public void testCreateTableTrailingNullOverwritingDefault() throws 
Exception {
String table = generateRandomString();
String ddl = "CREATE TABLE " + table + " (" +
"pk INTEGER PRIMARY KEY, " +
"def INTEGER DEFAULT 1 + 9)";

long ts = nextTimestamp();
Properties props = new Properties();
props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
Connection conn = DriverManager.getConnection(getUrl(), props);
conn

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-20 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15505920#comment-15505920
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/20/16 7:47 AM:
-

I attached a new patch implementing default values for both primary and 
row-value columns. 

There are a few issues though.

* After compiling a default value ParseNode into an Expression, it becomes a 
LiteralExpression. For `CURRENT_DATE()`, the ParseNode is stateless and the 
compiled `Expression.isConstant` is true so we aren’t able to throw an 
exception. Is there a existing expression compiler or a flag that will not 
convert the default value ParseNode to LiteralExpression?
Setting `requiresFinalEvaluation` did not change the result.

* DefaultValueExpression wraps a ProjectedColumnExpression in 
ExpressionCompiler. 
I modified `ProjectedColumnExpression.evaluate`  so that it returns true if the 
cell contains a null value.
But `KeyValueSchema.next` returns `null` for trailing nulls in a row so 
`ProjectedColumnExpression.evaluate` cannot differentiate between a trailing 
null and trailing default value.
If we change the return value contract of `KeyValueSchema.next`, it causes 
failures in other test cases (ie. SortMergeIT).
I’m not familiar with the serialization scheme for rows returned by the region 
servers, but I suspect that trailing nulls are trimmed, which might be why 
`KeyValueSchema.next` does not account for trailing nulls.

The following test case (which isn't in the patch) fails due to a trailing 
default value that is overwritten by a null value:
{code:java}

@Test
public void testCreateTableTrailingNullOverwritingDefault() throws 
Exception {
String table = generateRandomString();
String ddl = "CREATE TABLE " + table + " (" +
"pk INTEGER PRIMARY KEY, " +
"def INTEGER DEFAULT 1 + 9)";

long ts = nextTimestamp();
Properties props = new Properties();
props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.createStatement().execute(ddl);

String dml = "UPSERT INTO " + table + " VALUES (1, null)";
conn.createStatement().execute(dml);
conn.commit();

props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 
10));
conn = DriverManager.getConnection(getUrl(), props);

ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + 
table + " WHERE pk = 1");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals(0, rs.getInt(2));
assertTrue(rs.wasNull());
assertFalse(rs.next());
}
{code}


was (Author: kliew):
I attached a new patch implementing default values for both primary and 
row-value columns. 

There are a few issues though.

* After compiling a default value ParseNode into an Expression, it becomes a 
LiteralExpression. For `CURRENT_DATE()`, the ParseNode is stateless and the 
compiled `Expression.isConstant` is true so we aren’t able to throw an 
exception. Is there a existing expression compiler or a flag that will not 
convert the default value ParseNode to LiteralExpression?
Setting `requiresFinalEvaluation` did not change the result.

* DefaultValueExpression wraps a ProjectedColumnExpression in 
ExpressionCompiler. 
I modified `ProjectedColumnExpression.evaluate`  so that it returns true if the 
cell contains a null value.
But `KeyValueSchema.next` returns `null` for trailing nulls in a row 
`ProjectedColumnExpression.evaluate` cannot differentiate between a trailing 
null and trailing default value.
If we change the return value contract of `KeyValueSchema.next`, it causes 
failures in other test cases (ie. SortMergeIT).
I’m not familiar with the serialization scheme for rows returned by the region 
servers, but I suspect that trailing nulls are trimmed, which might be why 
`KeyValueSchema.next` does not account for trailing nulls.

The following test case (which isn't in the patch) fails due to a trailing 
default value that is overwritten by a null value:
{code:java}

@Test
public void testCreateTableTrailingNullOverwritingDefault() throws 
Exception {
String table = generateRandomString();
String ddl = "CREATE TABLE " + table + " (" +
"pk INTEGER PRIMARY KEY, " +
"def INTEGER DEFAULT 1 + 9)";

long ts = nextTimestamp();
Properties props = new Properties();
props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.createStatement().execute(ddl);

String dml = "UPSERT INTO " + table + " VALUES (1, null)";
conn.createStatement().execute(dml);
conn.commit();

props.setProp

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-16 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15497128#comment-15497128
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/16/16 7:15 PM:
-

If we consider the following case:

{noformat}
create table testdefault (pk integer primary key, test integer default 5);

upsert into testdefault values (1, null);

select * from testdefault;
{noformat}

We expect `1, ` but if we use `COALESCE` while retrieving the second 
column, would we get `1, 5`? 

I suppose CoalesceFunction will differentiate between null parse nodes and null 
values and that would give us the expected result?


was (Author: kliew):
If we consider the following case:

{noformat}
create table testdefault (pk integer primary key, test integer default 5);

upsert into testdefault values (1, null);

select * from testdefault;
{noformat}

We expect `1, ` but if we use `COALESCE` while retrieving the second 
column, would we get `1, 5`? 

I suppose CoalesceFunction will differentiate between null parse nodes and null 
values.

> 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
> Attachments: PHOENIX-476.2.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-16 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15497128#comment-15497128
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/16/16 7:16 PM:
-

If we consider the following case:

{noformat}
create table testdefault (pk integer primary key, test integer default 5);

upsert into testdefault values (1, null);

select * from testdefault;
{noformat}

We expect `1, ` but if we use `COALESCE` while retrieving the second 
column, would we get `1, 5`? 

I suppose CoalesceFunction will differentiate between null `Expression` and 
null values and that would give us the expected result?


was (Author: kliew):
If we consider the following case:

{noformat}
create table testdefault (pk integer primary key, test integer default 5);

upsert into testdefault values (1, null);

select * from testdefault;
{noformat}

We expect `1, ` but if we use `COALESCE` while retrieving the second 
column, would we get `1, 5`? 

I suppose CoalesceFunction will differentiate between null parse nodes and null 
values and that would give us the expected result?

> 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
> Attachments: PHOENIX-476.2.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-16 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15497128#comment-15497128
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/16/16 7:15 PM:
-

If we consider the following case:

{noformat}
create table testdefault (pk integer primary key, test integer default 5);

upsert into testdefault values (1, null);

select * from testdefault;
{noformat}

We expect `1, ` but if we use `COALESCE` while retrieving the second 
column, would we get `1, 5`? 

I suppose CoalesceFunction will differentiate between null parse nodes and null 
values.


was (Author: kliew):
If we consider the following case:

{noformat}
create table testdefault (pk integer primary key, test integer default 5);

upsert into testdefault values (1, null);

select * from testdefault;
{noformat}

We expect `1, ` but if we use `COALESCE` while retrieving the second 
column, would we get `1, 5`?

> 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
> Attachments: PHOENIX-476.2.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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-16 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15496816#comment-15496816
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/16/16 7:05 PM:
-

Thanks for the feedback [~jamestaylor].

I attached a patch with  values implemented for primary keys. The  expression 
node is compiled and cached in CreateTableCompiler and accessed in PTableImpl. 
Will the compiled expression persist between server restarts? Do I need to 
recompile the  expression in MetadataClient so that the  values of existing 
tables are cached on server-restart?

* For non-pk columns, if we evaluate the  expression once on  and wrap the 
column in `COALESCE` to replace `NULL` values with the  expression, the user 
can explicitly set values (for columns with default values) to `NULL` but the 
values will always be  as the  value. We can only make this optimization for 
columns that have a `NOT NULL` constraint.

* For nullable columns and stateful default expressions (or non-literal 
expressions), we will probably have to  the value during the `UPSERT` 
execution. In my previous patch, did I make changes in the right locations 
(UpsertCompiler) for these specific cases?


was (Author: kliew):
Thanks for the feedback [~jamestaylor].

I attached a patch with  values implemented for primary keys. The  expression 
node is compiled and cached in CreateTableCompiler and accessed in PTableImpl. 
Will the compiled expression persist between server restarts? Do I need to 
recompile the  expression in MetadataClient so that the  values of existing 
tables are cached on server-restart?

* For non-pk columns, if we evaluate the  expression once on  and wrap the 
column in `COALESCE` to replace `NULL` values with the  expression, the user 
can explicitly set values (for columns with  values) to `NULL` but the values 
will always be  as the  value. We can only make this optimization for columns 
that have a `NOT NULL` constraint.

* For nullable columns and stateful default expressions (or non-literal 
expressions), we will probably have to  the value during the `UPSERT` 
execution. In my previous patch, did I make changes in the right locations 
(UpsertCompiler) for these specific cases?

> 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
> Attachments: PHOENIX-476.2.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 

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-16 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15496816#comment-15496816
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/16/16 6:21 PM:
-

Thanks for the feedback [~jamestaylor].

I attached a patch with  values implemented for primary keys. The  expression 
node is compiled and cached in CreateTableCompiler and accessed in PTableImpl. 
Will the compiled expression persist between server restarts? Do I need to 
recompile the  expression in MetadataClient so that the  values of existing 
tables are cached on server-restart?

* For non-pk columns, if we evaluate the  expression once on  and wrap the 
column in `COALESCE` to replace `NULL` values with the  expression, the user 
can explicitly set values (for columns with  values) to `NULL` but the values 
will always be  as the  value. We can only make this optimization for columns 
that have a `NOT NULL` constraint.

* For nullable columns and stateful default expressions (or non-literal 
expressions), we will probably have to  the value during the `UPSERT` 
execution. In my previous patch, did I make changes in the right locations 
(UpsertCompiler) for these specific cases?


was (Author: kliew):
Thanks for the feedback [~jamestaylor].

I attached a patch with default values implemented for primary keys. The 
default expression node is compiled and cached in CreateTableCompiler and 
accessed in PTableImpl. Will the compiled expression persist between server 
restarts? Do I need to recompile the default expression in MetadataClient so 
that the default values of existing tables are cached on server-restart?

* For non-pk columns, if we evaluate the default expression once on read and 
wrap the column in `COALESCE` to replace `NULL` values with the default 
expression, the user can explicitly set values (for columns with default 
values) to `NULL` but the values will always be read as the default value. We 
can only make this optimization for columns that have a `NOT NULL` constraint.

* For nullable columns and stateful default expressions, we will probably have 
to store the value during the `UPSERT` execution. In my previous patch, did I 
make changes in the right locations (UpsertCompiler) for these specific cases?

> 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
> Attachments: PHOENIX-476.2.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 t

[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-08 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15471945#comment-15471945
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/8/16 6:24 PM:


I attached a patch implementing support for  in the CREATE statement. Is this 
the right approach? I will work on ALTER, DROP support, site documentation, and 
support for expressions in the  definition.

Should we save the  value in the SYSTEM.CATALOG table?

edit: I hadn't read the discussion above. I will take a look at that.


was (Author: kliew):
I attached a patch implementing support for  in the CREATE statement. Is this 
the right approach? I will work on ALTER, DROP support, site documentation, and 
support for expressions in the  definition.

Should we save the default value in the SYSTEM.CATALOG table?

> 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
> Attachments: 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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-07 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15471945#comment-15471945
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/7/16 10:21 PM:
-

I attached a patch implementing support for  in the CREATE statement. Is this 
the right approach? I will work on ALTER, DROP support, site documentation, and 
support for expressions in the  definition.

Should we save the default value in the SYSTEM.CATALOG table?


was (Author: kliew):
I attached a patch implementing support for  in the CREATE statement. Is this 
the right approach? I will work on ALTER, DROP support and support for 
expressions in the  definition.

Should we  the  value in the SYSTEM.CATALOG table?

> 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
> Attachments: 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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-07 Thread Kevin Liew (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15471945#comment-15471945
 ] 

Kevin Liew edited comment on PHOENIX-476 at 9/7/16 10:11 PM:
-

I attached a patch implementing support for  in the CREATE statement. Is this 
the right approach? I will work on ALTER, DROP support and support for 
expressions in the  definition.

Should we  the  value in the SYSTEM.CATALOG table?


was (Author: kliew):
I attached a patch implementing support for DEFAULT in the CREATE statement. I 
will work on ALTER, DROP support and support for expressions in the DEFAULT 
definition.

Should we store the default value in the SYSTEM.CATALOG table?

> 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
> Attachments: 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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-02 Thread James Taylor (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15459018#comment-15459018
 ] 

James Taylor edited comment on PHOENIX-476 at 9/2/16 4:50 PM:
--

[~kliew] - would you be interested in this one? We could do it in two stages:
# Allow only constants (i.e. ParseNode.isStateless() of true), like 5, 'foo', 
1.23.
# Allow things like CURRENT_DATE and NEXT VALUE FOR expressions which evaluate 
to constants, but must be evaluated per statement so they're a bit trickier.


was (Author: jamestaylor):
[~kliew] - would you be interested in this one? We could do it in two stages:
1. Allow only constants (i.e. ParseNode.isStateless() of true).
2. Allow things like CURRENT_DATE and NEXT VALUE FOR expressions which evaluate 
to constants, but must be evaluated per statement so they're a bit trickier.

> 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
>  Labels: enhancement
>
> 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)


[jira] [Comment Edited] (PHOENIX-476) Support declaration of DEFAULT in CREATE statement

2016-09-02 Thread James Taylor (JIRA)

[ 
https://issues.apache.org/jira/browse/PHOENIX-476?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15459018#comment-15459018
 ] 

James Taylor edited comment on PHOENIX-476 at 9/2/16 4:49 PM:
--

[~kliew] - would you be interested in this one? We could do it in two stages:
1. Allow only constants (i.e. ParseNode.isStateless() of true).
2. Allow things like CURRENT_DATE and NEXT VALUE FOR expressions which evaluate 
to constants, but must be evaluated per statement so they're a bit trickier.


was (Author: jamestaylor):
[~kliew] - would you be interested in this one? We could do it in two stages:
#. Allow only constants (i.e. ParseNode.isStateless() of true).
#. Allow things like CURRENT_DATE and NEXT VALUE FOR expressions which evaluate 
to constants, but must be evaluated per statement so they're a bit trickier.

> 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
>  Labels: enhancement
>
> 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)