Skip to content

PostgreSQL json fields, how to use them? #252

Open

Description

@badmansan

Version: 3.0.5

Bug Description

I want to use json field in WHERE

Steps To Reproduce

Create simple table:

CREATE TABLE "log" (
    "data" json NOT NULL
);

INSERT INTO "log" ("data") VALUES
('{"code":2}');

Try to run query:

$db->query('SELECT * FROM log WHERE', [
	"data->>'code'" => 2,
]);

Expected Behavior

Result SQL must be (query in postgres_query.log)

SELECT * FROM log WHERE (data->>'code' = $1)

but I got

ERROR:  column "data->>'code'" does not exist at character 26
STATEMENT:  SELECT * FROM log WHERE ("data->>'code'" = $1)

Possible Solution

Nette need to somehow avoid quotes in the name of such fields

Activity

  1. dg commented on Feb 13, 2020

    @dg
    Member

    Because keys are always quoted, I think the best way is to use Nette\Database\SqlLiteral

    $db->query('SELECT * FROM log WHERE', [
    	new SqlLiteral("data->>'code' = ?", [2]),
    ]);
  2. badmansan commented on Feb 13, 2020

    @badmansan
    Author

    Maybe you're right. I just don't like how the resulting code looks in case of complex queries.

    $i = 0;
    
    foreach ($keyIds as $key) {
    	$literal = [
    		$this->db::literal("data->>'code' = ?", $event),
    		$this->db::literal("data->'data'->>'key' = ?", $key),
    	];
    
    	if ($result) {
    		$literal[] = $this->db::literal("data->'data'->>'result'", $result);
    	}
    
    	$params[$i++] = $this->db::literal('?and', $literal);
    }
    
    $this->query($sql, $this->db::literal('?and', $params));

    instead of

    foreach ($keyIds as $key) {
    	$params = [
    		"data->>'ev_code'" => $event,
    		"data->'data'->>'key'" => $key,
    	];
    
    	if ($result) {
    		$params[] = ["data->data'->>'result'" => $result];
    	}
    }
    
    $this->query($sql, ...$params);
  3. dg commented on Feb 14, 2020

    @dg
    Member

    Yes, problem is that data->>'code' is not column, it is column data and JSON operator ->> and string 'code'. And NDB is not ready for it. Support for JSON could certainly be added…

  4. otuhacek commented on Mar 16, 2021

    @otuhacek
    Contributor

    I have similar problem. When filtering with fields->>'myNote' LIKE (?) it wraps myNote with quotes "fields"->>'"myNote"' LIKE (?). So I need to go with SqlLiteral for now. Support for these specialities would be nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions