Skip to content

Commit

Permalink
Remove is_json and is_not_json methods from the pg_json_ops extension…
Browse files Browse the repository at this point in the history
…, as the support was removed in PostgreSQL 15 beta 4
  • Loading branch information
jeremyevans committed Sep 14, 2022
1 parent 93646b1 commit 98f8c9b
Show file tree
Hide file tree
Showing 4 changed files with 2 additions and 164 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
=== master

* Remove is_json and is_not_json methods from the pg_json_ops extension, as the support was removed in PostgreSQL 15 beta 4 (jeremyevans)

* Fix handling of timestamps before the date of calendar reform when using pg_extended_date_support extension on Ruby 3.2 (jeremyevans)

=== 5.60.1 (2022-09-02)
Expand Down
52 changes: 0 additions & 52 deletions lib/sequel/extensions/pg_json_ops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,6 @@
# c = Sequel.pg_jsonb_op(:c)
# DB[:t].update(c['key1'] => 1.to_json, c['key2'] => "a".to_json)
#
# On PostgreSQL 15+, the <tt>IS [NOT] JSON</tt> operator is supported:
#
# j.is_json # j IS JSON
# j.is_json(type: :object) # j IS JSON OBJECT
# j.is_json(type: :object, unique: true) # j IS JSON OBJECT WITH UNIQUE
# j.is_not_json # j IS NOT JSON
# j.is_json(type: :array) # j IS NOT JSON ARRAY
# j.is_json(unique: true) # j IS NOT JSON WITH UNIQUE
#
# If you are also using the pg_json extension, you should load it before
# loading this extension. Doing so will allow you to use the #op method on
# JSONHash, JSONHarray, JSONBHash, and JSONBArray, allowing you to perform json/jsonb operations
Expand Down Expand Up @@ -160,18 +151,6 @@ class JSONBaseOp < Sequel::SQL::Wrapper
GET_PATH = ["(".freeze, " #> ".freeze, ")".freeze].freeze
GET_PATH_TEXT = ["(".freeze, " #>> ".freeze, ")".freeze].freeze

IS_JSON = ["(".freeze, " IS JSON".freeze, "".freeze, ")".freeze].freeze
IS_NOT_JSON = ["(".freeze, " IS NOT JSON".freeze, "".freeze, ")".freeze].freeze
EMPTY_STRING = Sequel::LiteralString.new('').freeze
WITH_UNIQUE = Sequel::LiteralString.new(' WITH UNIQUE').freeze
IS_JSON_MAP = {
nil => EMPTY_STRING,
:value => Sequel::LiteralString.new(' VALUE').freeze,
:scalar => Sequel::LiteralString.new(' SCALAR').freeze,
:object => Sequel::LiteralString.new(' OBJECT').freeze,
:array => Sequel::LiteralString.new(' ARRAY').freeze
}.freeze

# Get JSON array element or object field as json. If an array is given,
# gets the object at the specified path.
#
Expand Down Expand Up @@ -254,30 +233,6 @@ def get_text(key)
end
end

# Return whether the json object can be parsed as JSON.
#
# Options:
# :type :: Check whether the json object can be parsed as a specific type
# of JSON (:value, :scalar, :object, :array).
# :unique :: Check JSON objects for unique keys.
#
# json_op.is_json # json IS JSON
# json_op.is_json(type: :object) # json IS JSON OBJECT
# json_op.is_json(unique: true) # json IS JSON WITH UNIQUE
def is_json(opts=OPTS)
_is_json(IS_JSON, opts)
end

# Return whether the json object cannot be parsed as JSON. The opposite
# of #is_json. See #is_json for options.
#
# json_op.is_not_json # json IS NOT JSON
# json_op.is_not_json(type: :object) # json IS NOT JSON OBJECT
# json_op.is_not_json(unique: true) # json IS NOT JSON WITH UNIQUE
def is_not_json(opts=OPTS)
_is_json(IS_NOT_JSON, opts)
end

# Returns a set of keys AS text in the json object.
#
# json_op.keys # json_object_keys(json)
Expand Down Expand Up @@ -331,13 +286,6 @@ def typeof

private

# Internals of IS [NOT] JSON support
def _is_json(lit_array, opts)
raise Error, "invalid is_json :type option: #{opts[:type].inspect}" unless type = IS_JSON_MAP[opts[:type]]
unique = opts[:unique] ? WITH_UNIQUE : EMPTY_STRING
Sequel::SQL::BooleanExpression.new(:NOOP, Sequel::SQL::PlaceholderLiteralString.new(lit_array, [self, type, unique]))
end

# Return a placeholder literal with the given str and args, wrapped
# in an JSONOp or JSONBOp, used by operators that return json or jsonb.
def json_op(str, args)
Expand Down
39 changes: 0 additions & 39 deletions spec/adapters/postgres_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3943,45 +3943,6 @@ def left_item_id
Sequel.pg_jsonb_op(Sequel[:i])['d'] => Sequel.pg_jsonb('e'=>4))
@db[:items].all.must_equal [{:i=>{'a'=>{'b'=>2, 'c'=>3}, 'd'=>{'e'=>4}}}]
end if DB.server_version >= 140000 && json_type == :jsonb

it "15 #{json_type} operations/functions with pg_json_ops" do
meth = Sequel.method(:"pg_#{json_type}_op")
@db.get(meth.call('{}').is_json).must_equal true
@db.get(meth.call('null').is_json).must_equal true
@db.get(meth.call('1').is_json).must_equal true
@db.get(meth.call('"a"').is_json).must_equal true
@db.get(meth.call('[]').is_json).must_equal true
@db.get(meth.call('').is_json).must_equal false

@db.get(meth.call('1').is_json(:type=>:scalar)).must_equal true
@db.get(meth.call('null').is_json(:type=>:value)).must_equal true
@db.get(meth.call('{}').is_json(:type=>:object)).must_equal true
@db.get(meth.call('{}').is_json(:type=>:array)).must_equal false
@db.get(meth.call('{"a": 1, "a": 2}').is_json(:type=>:object, :unique=>true)).must_equal false
@db.get(meth.call('{"a": 1, "b": 2}').is_json(:type=>:object, :unique=>true)).must_equal true
@db.get(meth.call('[]').is_json(:type=>:object, :unique=>true)).must_equal false
@db.get(meth.call('{"a": 1, "a": 2}').is_json(:unique=>true)).must_equal false
@db.get(meth.call('{"a": 1, "b": 2}').is_json(:unique=>true)).must_equal true
@db.get(meth.call('[]').is_json(:unique=>true)).must_equal true

@db.get(meth.call('{}').is_not_json).must_equal false
@db.get(meth.call('null').is_not_json).must_equal false
@db.get(meth.call('1').is_not_json).must_equal false
@db.get(meth.call('"a"').is_not_json).must_equal false
@db.get(meth.call('[]').is_not_json).must_equal false
@db.get(meth.call('').is_not_json).must_equal true

@db.get(meth.call('1').is_not_json(:type=>:scalar)).must_equal false
@db.get(meth.call('null').is_not_json(:type=>:value)).must_equal false
@db.get(meth.call('{}').is_not_json(:type=>:object)).must_equal false
@db.get(meth.call('{}').is_not_json(:type=>:array)).must_equal true
@db.get(meth.call('{"a": 1, "a": 2}').is_not_json(:type=>:object, :unique=>true)).must_equal true
@db.get(meth.call('{"a": 1, "b": 2}').is_not_json(:type=>:object, :unique=>true)).must_equal false
@db.get(meth.call('[]').is_not_json(:type=>:object, :unique=>true)).must_equal true
@db.get(meth.call('{"a": 1, "a": 2}').is_not_json(:unique=>true)).must_equal true
@db.get(meth.call('{"a": 1, "b": 2}').is_not_json(:unique=>true)).must_equal false
@db.get(meth.call('[]').is_not_json(:unique=>true)).must_equal false
end if DB.server_version >= 150000
end
end if DB.server_version >= 90200

Expand Down
73 changes: 0 additions & 73 deletions spec/extensions/pg_json_ops_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,79 +111,6 @@ def @db.server_version(*); 130000; end
@l[@jb.extract_text('a') + 'a'].must_equal "(jsonb_extract_path_text(j, 'a') || 'a')"
end

it "should have #is_json work without arguments" do
@l[@j.is_json].must_equal "(j IS JSON)"
@l[@jb.is_json].must_equal "(j IS JSON)"
end

it "should have #is_json respect :type option" do
[@j, @jb].each do |j|
@l[j.is_json(:type=>:value)].must_equal "(j IS JSON VALUE)"
@l[j.is_json(:type=>:scalar)].must_equal "(j IS JSON SCALAR)"
@l[j.is_json(:type=>:object)].must_equal "(j IS JSON OBJECT)"
@l[j.is_json(:type=>:array)].must_equal "(j IS JSON ARRAY)"
end
end

it "should have #is_json respect :unique option" do
@l[@j.is_json(:unique=>true)].must_equal "(j IS JSON WITH UNIQUE)"
@l[@jb.is_json(:unique=>true)].must_equal "(j IS JSON WITH UNIQUE)"
end

it "should have #is_json respect :type and :unique options" do
[@j, @jb].each do |j|
@l[j.is_json(:type=>:value, :unique=>true)].must_equal "(j IS JSON VALUE WITH UNIQUE)"
@l[j.is_json(:type=>:scalar, :unique=>true)].must_equal "(j IS JSON SCALAR WITH UNIQUE)"
@l[j.is_json(:type=>:object, :unique=>true)].must_equal "(j IS JSON OBJECT WITH UNIQUE)"
@l[j.is_json(:type=>:array, :unique=>true)].must_equal "(j IS JSON ARRAY WITH UNIQUE)"
end
end

it "should have #is_json return an SQL::BooleanExpression" do
@l[~@j.is_json].must_equal "NOT (j IS JSON)"
@l[~@jb.is_json].must_equal "NOT (j IS JSON)"
end

it "should have #is_not_json work without arguments" do
@l[@j.is_not_json].must_equal "(j IS NOT JSON)"
@l[@jb.is_not_json].must_equal "(j IS NOT JSON)"
end

it "should have #is_not_json respect :type option" do
[@j, @jb].each do |j|
@l[j.is_not_json(:type=>:value)].must_equal "(j IS NOT JSON VALUE)"
@l[j.is_not_json(:type=>:scalar)].must_equal "(j IS NOT JSON SCALAR)"
@l[j.is_not_json(:type=>:object)].must_equal "(j IS NOT JSON OBJECT)"
@l[j.is_not_json(:type=>:array)].must_equal "(j IS NOT JSON ARRAY)"
end
end

it "should have #is_not_json respect :unique option" do
@l[@j.is_not_json(:unique=>true)].must_equal "(j IS NOT JSON WITH UNIQUE)"
@l[@jb.is_not_json(:unique=>true)].must_equal "(j IS NOT JSON WITH UNIQUE)"
end

it "should have #is_not_json respect :type and :unique options" do
[@j, @jb].each do |j|
@l[j.is_not_json(:type=>:value, :unique=>true)].must_equal "(j IS NOT JSON VALUE WITH UNIQUE)"
@l[j.is_not_json(:type=>:scalar, :unique=>true)].must_equal "(j IS NOT JSON SCALAR WITH UNIQUE)"
@l[j.is_not_json(:type=>:object, :unique=>true)].must_equal "(j IS NOT JSON OBJECT WITH UNIQUE)"
@l[j.is_not_json(:type=>:array, :unique=>true)].must_equal "(j IS NOT JSON ARRAY WITH UNIQUE)"
end
end

it "should have #is_not_json return an SQL::BooleanExpression" do
@l[~@j.is_not_json].must_equal "NOT (j IS NOT JSON)"
@l[~@jb.is_not_json].must_equal "NOT (j IS NOT JSON)"
end

it "should have #is_json and #is_not_json raise for invalid :type" do
proc{@j.is_json(:type=>:foo)}.must_raise Sequel::Error
proc{@jb.is_json(:type=>:foo)}.must_raise Sequel::Error
proc{@j.is_not_json(:type=>:foo)}.must_raise Sequel::Error
proc{@jb.is_not_json(:type=>:foo)}.must_raise Sequel::Error
end

it "should have #keys use the json_object_keys function" do
@l[@j.keys].must_equal "json_object_keys(j)"
@l[@jb.keys].must_equal "jsonb_object_keys(j)"
Expand Down

0 comments on commit 98f8c9b

Please sign in to comment.