<commit_before>////
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
////

= TinkerPop 3.5.0

image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/images/gremlin-sleeping-beauty.png[width=225]

*The Sleeping Gremlin: No. 18 Entr'acte symphonique*

== TinkerPop 3.5.0

*Release Date: NOT OFFICIALLY RELEASED YET*

Please see the link:https://github.com/apache/tinkerpop/blob/3.5.0/CHANGELOG.asciidoc#release-3-5-0[changelog] for a complete list of all the modifications that are part of this release.

=== Upgrading for Users

==== Gryo Usage

Since the first release of TinkerPop 3.x, Gryo has been the default serialization format for Gremlin Server and
Java Driver. It was also used as the default serialization format for Gremlin Console remote connectivity to Gremlin
Server. As of this release, Gryo has been replaced as the default by GraphBinary. All packaged configuration files
and programmatic defaults have been modified as such.

It is still possible to utilize Gryo as a message serialization format by modifying Gremlin Server configuration files
to include the appropriate Gryo configurations. If using Gryo, do not user earlier versions of the driver and server
with 3.5.0. Use a 3.5.0 client to connect to a 3.5.0 server. Generally speaking, mixed version combinations will
appear to work properly, but problems will likely occur during general course of usage and it is therefore not
advisable to take this approach.

For best compatibility between 3.4.x and 3.5.x, please use GraphBinary.

link:https://issues.apache.org/jira/browse/TINKERPOP-2259[TINKERPOP-2259]

==== Configuration Upgrade

There is a major breaking change in the use of `Configuration` objects. Prior to 3.5.0, `Configuration` objects were
from the Apache Commons `commons-configuration` library, but in this version, they are of `commons-configuration2`.
While this is a breaking change, the fix for most implementations will be quite simple, Simply, change the import
statements from:

[source,text]
----
org.apache.commons.configuration.*
----

to

[source,text]
----
org.apache.commons.configuration2.*
----

It is also worth noting that default list handling in configurations is treated differently. TinkerPop largely
disabled the default list handling approach in `Configuration` 1.x, but if that functionality is still needed, it can
be reclaimed by setting the `LegacyListDelimiterHandler` - details for doing taking this step and other relevant
upgrade information can be found in the link:https://commons.apache.org/proper/commons-configuration/userguide/upgradeto2_0.html[2.x Upgrade Documentation].

See: link:https://issues.apache.org/jira/browse/TINKERPOP-2185[TINKERPOP-2185]

==== Use of null

Gremlin has traditionally disallowed `null` as a value in traversals and not always in consistent ways:

[source,text]
----
gremlin> g.inject(1, null, null, 2, null)
java.lang.NullPointerException
Type ':help' or ':h' for help.
Display stack trace? [yN]n
gremlin> g.V().has('person','name','marko').property('age', null)
The AddPropertyStep does not have a provided value: AddPropertyStep({key=[age]})
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> g.addV("person").property("name", 'stephen').property("age", null)
==>v[13]
gremlin> g.V().has('person','name','stephen').elementMap()
==>[id:13,label:person,name:stephen]
gremlin> g.V().constant(null)
gremlin>
----

Note how `null` can produce exception behavior or act as a filter. For 3.5.0, TinkerPop has not only made `null` usage
consistent, but has also made it an allowable value within a `Traversal`:

[source,text]
----
gremlin> g.inject(1, null, null, 2, null)
==>1
==>null
==>null
==>null
==>2
gremlin> g.addV("person").property("name", 'stephen').property("age", null)
==>v[13]
gremlin> g.V().has('person','name','stephen').elementMap()
==>[id:13,label:person,name:stephen,age:null]
gremlin> g.V().has('person','age',null)
==>v[13]
gremlin> g.V().constant(null)
==>null
==>null
==>null
==>null
==>null
==>null
----

Note that the above examples use TinkerGraph which now supports `null` as a property value (though it can be configured
to work in the prior fashion) and all graphs may not support this feature (for example, Neo4j does not). Please be
sure to check the new `supportsNullPropertyValues()` feature (or their documentation) to determine if the `Graph`
implementation allows `null` in this same fashion.

As a final consideration, there was a bit of inconsistency in the handling of `null` in calls to `property()`
depending on the type of mutation being executed demonstrated as follows in earlier versions:

[source,text]
----
gremlin> g.V(1).property("x", 1).property("y", null).property("z", 2)
The AddPropertyStep does not have a provided value: AddPropertyStep({key=[y]})
Type ':help' or ':h' for help.
Display stack trace? [yN]N
gremlin> g.addV("test").property("x", 1).property("y", null).property("z", 2)
==>v[13]
gremlin> g.V(13).properties()
==>vp[x->1]
==>vp[z->2]
----

In this release, this behavior has been altered to become consistent. First, assuming `null` is not supported as a
property value:

[source,text]
----
gremlin> g.V(1).property("x", 1).property("y", null).property("z", 2)
Property value can not be null
Type ':help' or ':h' for help.
Display stack trace? [yN]n
gremlin> g.addV().property("x", 1).property("y", null).property("z", 2)
Property value can not be null
Type ':help' or ':h' for help.
Display stack trace? [yN]
----

Then, assuming `null` is supported as a property value:

[source,text]
----
gremlin> g.V(1).property("x", 1).property("y", null).property("z", 2)
==>v[1]
gremlin> g.addV().property("x", 1).property("y", null).property("z", 2)
==>v[15]
----

See: link:https://issues.apache.org/jira/browse/TINKERPOP-2235[TINKERPOP-2235],
link:https://issues.apache.org/jira/browse/TINKERPOP-2099[TINKERPOP-2099]
<commit_msg>TINKERPOP-2235 Improved upgrade docs for null handling<commit_after>////
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
////

= TinkerPop 3.5.0

image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/images/gremlin-sleeping-beauty.png[width=225]

*The Sleeping Gremlin: No. 18 Entr'acte symphonique*

== TinkerPop 3.5.0

*Release Date: NOT OFFICIALLY RELEASED YET*

Please see the link:https://github.com/apache/tinkerpop/blob/3.5.0/CHANGELOG.asciidoc#release-3-5-0[changelog] for a complete list of all the modifications that are part of this release.

=== Upgrading for Users

==== Gryo Usage

Since the first release of TinkerPop 3.x, Gryo has been the default serialization format for Gremlin Server and
Java Driver. It was also used as the default serialization format for Gremlin Console remote connectivity to Gremlin
Server. As of this release, Gryo has been replaced as the default by GraphBinary. All packaged configuration files
and programmatic defaults have been modified as such.

It is still possible to utilize Gryo as a message serialization format by modifying Gremlin Server configuration files
to include the appropriate Gryo configurations. If using Gryo, do not user earlier versions of the driver and server
with 3.5.0. Use a 3.5.0 client to connect to a 3.5.0 server. Generally speaking, mixed version combinations will
appear to work properly, but problems will likely occur during general course of usage and it is therefore not
advisable to take this approach.

For best compatibility between 3.4.x and 3.5.x, please use GraphBinary.

link:https://issues.apache.org/jira/browse/TINKERPOP-2259[TINKERPOP-2259]

==== Configuration Upgrade

There is a major breaking change in the use of `Configuration` objects. Prior to 3.5.0, `Configuration` objects were
from the Apache Commons `commons-configuration` library, but in this version, they are of `commons-configuration2`.
While this is a breaking change, the fix for most implementations will be quite simple, Simply, change the import
statements from:

[source,text]
----
org.apache.commons.configuration.*
----

to

[source,text]
----
org.apache.commons.configuration2.*
----

It is also worth noting that default list handling in configurations is treated differently. TinkerPop largely
disabled the default list handling approach in `Configuration` 1.x, but if that functionality is still needed, it can
be reclaimed by setting the `LegacyListDelimiterHandler` - details for doing taking this step and other relevant
upgrade information can be found in the link:https://commons.apache.org/proper/commons-configuration/userguide/upgradeto2_0.html[2.x Upgrade Documentation].

See: link:https://issues.apache.org/jira/browse/TINKERPOP-2185[TINKERPOP-2185]

==== Use of null

Gremlin has traditionally disallowed `null` as a value in traversals and not always in consistent ways:

[source,text]
----
gremlin> g.inject(1, null, null, 2, null)
java.lang.NullPointerException
Type ':help' or ':h' for help.
Display stack trace? [yN]n
gremlin> g.V().has('person','name','marko').property('age', null)
The AddPropertyStep does not have a provided value: AddPropertyStep({key=[age]})
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> g.addV("person").property("name", 'stephen').property("age", null)
==>v[13]
gremlin> g.V().has('person','name','stephen').elementMap()
==>[id:13,label:person,name:stephen]
gremlin> g.V().constant(null)
gremlin>
----

Note how `null` can produce exception behavior or act as a filter. For 3.5.0, TinkerPop has not only made `null` usage
consistent, but has also made it an allowable value within a `Traversal`:

[source,text]
----
gremlin> g.inject(1, null, null, 2, null)
==>1
==>null
==>null
==>null
==>2
gremlin> g.addV("person").property("name", 'stephen').property("age", null)
==>v[13]
gremlin> g.V().has('person','name','stephen').elementMap()
==>[id:13,label:person,name:stephen,age:null]
gremlin> g.V().has('person','age',null)
==>v[13]
gremlin> g.V().constant(null)
==>null
==>null
==>null
==>null
==>null
==>null
----

Note that the above examples use TinkerGraph which now supports `null` as a property value (though it can be configured
to work in the prior fashion) and all graphs may not support this feature (for example, Neo4j does not). Please be
sure to check the new `supportsNullPropertyValues()` feature (or their documentation) to determine if the `Graph`
implementation allows `null` in this same fashion.

As a final consideration, there was a bit of inconsistency in the handling of `null` in calls to `property()`
depending on the type of mutation being executed demonstrated as follows in earlier versions:

[source,text]
----
gremlin> g.V(1).property("x", 1).property("y", null).property("z", 2)
The AddPropertyStep does not have a provided value: AddPropertyStep({key=[y]})
Type ':help' or ':h' for help.
Display stack trace? [yN]N
gremlin> g.addV("test").property("x", 1).property("y", null).property("z", 2)
==>v[13]
gremlin> g.V(13).properties()
==>vp[x->1]
==>vp[z->2]
----

In this release, this behavior has been altered to become consistent. First, assuming `null` is not supported as a
property value:

[source,text]
----
gremlin> g.V(1).property("x", 1).property("y", null).property("z", 2)
Property value can not be null
Type ':help' or ':h' for help.
Display stack trace? [yN]n
gremlin> g.addV().property("x", 1).property("y", null).property("z", 2)
Property value can not be null
Type ':help' or ':h' for help.
Display stack trace? [yN]
----

Then, assuming `null` is supported as a property value:

[source,text]
----
gremlin> g.V(1).property("x", 1).property("y", null).property("z", 2)
==>v[1]
gremlin> g.addV().property("x", 1).property("y", null).property("z", 2)
==>v[15]
----

In conclusion, this change in greater support of `null` may affect the behavior of existing traversals written in past
versions of TinkerPop as it is no longer possible to rely on `null` to expect a filtering action for traversers.
Please review existing Gremlin carefully to ensure that there are no unintended consequences of this change and that
there are no opportunities to improve existing logic to take greater advantage of this expansion of `null` semantics.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-2235[TINKERPOP-2235],
link:https://issues.apache.org/jira/browse/TINKERPOP-2099[TINKERPOP-2099]

{'fraction_non_alphanumeric': 0.12117225754585982, 'fraction_numerical': 0.017832346707593365, 'mean_word_length': 4.975545851528384, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 85, 'https://': 14, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2219584', 'n_tokens_mistral': 4345, 'n_tokens_neox': 4084, 'n_words': 1643}