Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PostgreSQL json fields, how to use them? #252

Open
badmansan opened this issue Feb 11, 2020 · 4 comments
Open

PostgreSQL json fields, how to use them? #252

badmansan opened this issue Feb 11, 2020 · 4 comments

Comments

@badmansan
Copy link

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

@dg
Copy link
Member

dg commented Feb 13, 2020

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]),
]);

@badmansan
Copy link
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);

@dg
Copy link
Member

dg commented Feb 14, 2020

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…

@otuhacek
Copy link
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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants