nette/database

Bad used condition parameters.

Closed this issue · 2 comments

  • bug report? yes
  • version: 2.4 dev-master#d56890f959f3cff135a4bbef36e8cfa380a3cb9c

Description

Hi,

i want select data (many) via foreing id and join one row from next table and sql is bad builded, where condition ignore parameter. where('column', $value).
Or if i try write condition like where('column = ?', $value) a get exception Nette\InvalidArgumentException('Argument count does not match placeholder count.')

Expected output sql:

SELECT `responses`.`id`, `responses`.`insert_date`, `response_confirms`.`confirm_date` 
FROM `responses` 
LEFT JOIN `response_confirms` ON `responses`.`response_confirms_id` = `response_confirms`.`id` 
WHERE (`responses`.`form_id` = 1)

But i get:

SELECT `responses`.`id`, `responses`.`insert_date`, `response_confirms`.`confirm_date` 
FROM `responses` 
LEFT JOIN `response_confirms` ON `responses`.`response_confirms_id` = `response_confirms`.`id` 
WHERE (`responses`.`form_id`) AND (1) -- here is bug

sql schema

SET NAMES utf8;
SET time_zone = '+00:00';
SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';

CREATE TABLE `responses` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `form_id` bigint(20) unsigned DEFAULT NULL,
  `response_confirms_id` bigint(20) unsigned DEFAULT NULL,
  `insert_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `response_confirm_id` (`response_confirms_id`),
  CONSTRAINT `responses_ibfk_1` FOREIGN KEY (`response_confirms_id`) REFERENCES `response_confirms` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

INSERT INTO `responses` (`id`, `form_id`, `response_confirms_id`, `insert_date`) VALUES
(1,	1,	2,	'2017-01-09 06:19:43'),
(2,	1,	3,	'2017-01-09 06:19:44');

CREATE TABLE `response_confirms` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `response_id` bigint(20) unsigned NOT NULL,
  `description` varchar(30) COLLATE utf8_czech_ci NOT NULL,
  `confirm_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `response_id` (`response_id`),
  CONSTRAINT `response_confirms_ibfk_4` FOREIGN KEY (`response_id`) REFERENCES `responses` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

INSERT INTO `response_confirms` (`id`, `response_id`, `description`, `confirm_date`) VALUES
(1,	1,	'Add confirm',	'2017-01-09 06:20:16'),
(2,	1,	'Remove confirm',	'2017-01-09 06:20:33'),
(3,	2,	'Add confirm',	'2017-01-09 06:20:51');

prepare environment

git clone git@github.com:nette/database.git nette-database
cd nette-database
composer install
mkdir temp
touch run.php

php script run.php

<?php

require __DIR__ . '/vendor/autoload.php';

$config = [
	'dsn' => 'mysql:host=127.0.0.1;dbname=nette_test',
	'user' => 'root',
	'password' => ''
];

$connection = new Nette\Database\Connection($config['dsn'], $config['user'], $config['password']);
$storage = new Nette\Caching\Storages\FileStorage(__DIR__ . '/temp');
$structure = new \Nette\Database\Structure($connection, $storage);
$context = new Nette\Database\Context($connection, $structure);


$sql = $context->table('responses')
	->select('responses.id, responses.insert_date, response_confirms.confirm_date')
	->where(['responses.form_id', 1]);

echo($sql->getSql()); # sql is broken


$sql = $context->table('responses')
	->select('responses.id, responses.insert_date, response_confirms.confirm_date')
	->where(['responses.form_id = ?', 1]);

echo($sql->getSql()); # throw exception
dg commented

In code you have where(['responses.form_id', 1]), correct form is where('responses.form_id', 1), as mentioned in text.

I'm so much sorry. :) My bad.