com php-src: Implement FR #74217: deterministic sqlite functions: NEWS ext/pdo_sqlite/pdo_sqlite.c ext/pdo_sqlite/sqlite_d river.c ext/pdo_sqlite/tests/pdo_sqlite_createfunctio n_with_flags.phpt ext/sqlite3/sqlite3.c ext/sql ite3/tests/sqlite3_37_createfunction_flags.phpt

[email protected] (Nikita Popov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    fbf0e0587f8455525466e6d4ab2c1f0fc24bfe26
Author:    andrewnester <[email protected]>         Fri, 10 Mar 2017 20:34:23 +0300
Committer: Nikita Popov <[email protected]>      Sun, 12 Mar 2017 17:03:00 +0100
Parents:   280e8dafe472e6789fdcfebd3dade4c0705b0134
Branches:  PHP-7.1 master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=fbf0e0587f8455525466e6d4ab2c1f0fc24bfe26

Log:
Implement FR #74217: deterministic sqlite functions

Bugs:
https://bugs.php.net/74217

Changed paths:
  M  NEWS
  M  ext/pdo_sqlite/pdo_sqlite.c
  M  ext/pdo_sqlite/sqlite_driver.c
  A  ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt
  M  ext/sqlite3/sqlite3.c
  A  ext/sqlite3/tests/sqlite3_37_createfunction_flags.phpt


Diff:
diff --git a/NEWS b/NEWS
index 6581516..d8271ef 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,10 @@ PHP                                                                        NEWS
 - SPL:
   . Fixed bug #74058 (ArrayObject can not notice changes). (Andrew Nester)
 
+- Sqlite:
+  . Implemented FR #74217 (Allow creation of deterministic sqlite functions).
+    (Andrew Nester)
+
 . Streams:
   . Fixed bug #74216 (Correctly fail on invalid IP address ports). (Sara)
 
diff --git a/ext/pdo_sqlite/pdo_sqlite.c b/ext/pdo_sqlite/pdo_sqlite.c
index c5bba02..621123b 100644
--- a/ext/pdo_sqlite/pdo_sqlite.c
+++ b/ext/pdo_sqlite/pdo_sqlite.c
@@ -69,6 +69,8 @@ ZEND_GET_MODULE(pdo_sqlite)
 /* {{{ PHP_MINIT_FUNCTION */
 PHP_MINIT_FUNCTION(pdo_sqlite)
 {
+	REGISTER_PDO_CLASS_CONST_LONG("SQLITE_DETERMINISTIC", (zend_long)SQLITE_DETERMINISTIC);
+
 	return php_pdo_register_driver(&pdo_sqlite_driver);
 }
 /* }}} */
diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c
index 3f9b51d..71bac85 100644
--- a/ext/pdo_sqlite/sqlite_driver.c
+++ b/ext/pdo_sqlite/sqlite_driver.c
@@ -505,7 +505,7 @@ static int php_sqlite3_collation_callback(void *context,
 	return ret;
 }
 
-/* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount])
+/* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount, int flags])
    Registers a UDF with the sqlite db handle */
 static PHP_METHOD(SQLite, sqliteCreateFunction)
 {
@@ -514,13 +514,14 @@ static PHP_METHOD(SQLite, sqliteCreateFunction)
 	char *func_name;
 	size_t func_name_len;
 	zend_long argc = -1;
+	zend_long flags = 0;
 	zend_string *cbname = NULL;
 	pdo_dbh_t *dbh;
 	pdo_sqlite_db_handle *H;
 	int ret;
 
-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz|l",
-			&func_name, &func_name_len, &callback, &argc)) {
+	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz|ll",
+			&func_name, &func_name_len, &callback, &argc, &flags)) {
 		RETURN_FALSE;
 	}
 
@@ -538,7 +539,7 @@ static PHP_METHOD(SQLite, sqliteCreateFunction)
 
 	func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
 
-	ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
+	ret = sqlite3_create_function(H->db, func_name, argc, flags | SQLITE_UTF8,
 			func, php_sqlite3_func_callback, NULL, NULL);
 	if (ret == SQLITE_OK) {
 		func->funcname = estrdup(func_name);
diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt
new file mode 100644
index 0000000..4f0b675
--- /dev/null
+++ b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt
@@ -0,0 +1,38 @@
+--TEST--
+PDO_sqlite: Testing sqliteCreateFunction() with flags
+--SKIPIF--
+<?php if (!extension_loaded('pdo_sqlite')) print 'skip not loaded'; ?>
+--FILE--
+<?php
+
+$db = new pdo('sqlite::memory:');
+
+$db->query('CREATE TABLE IF NOT EXISTS foobar (id INT AUTO INCREMENT, name TEXT)');
+
+$db->query('INSERT INTO foobar VALUES (NULL, "PHP")');
+$db->query('INSERT INTO foobar VALUES (NULL, "PHP6")');
+
+
+$db->sqliteCreateFunction('testing', function($v) { return strtolower($v); }, 1, PDO::SQLITE_DETERMINISTIC);
+
+
+foreach ($db->query('SELECT testing(name) FROM foobar') as $row) {
+	var_dump($row);
+}
+
+$db->query('DROP TABLE foobar');
+
+?>
+--EXPECTF--
+array(2) {
+  ["testing(name)"]=>
+  string(3) "php"
+  [0]=>
+  string(3) "php"
+}
+array(2) {
+  ["testing(name)"]=>
+  string(4) "php6"
+  [0]=>
+  string(4) "php6"
+}
diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c
index f947674..5a796e1 100644
--- a/ext/sqlite3/sqlite3.c
+++ b/ext/sqlite3/sqlite3.c
@@ -891,7 +891,7 @@ static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, in
 }
 /* }}} */
 
-/* {{{ proto bool SQLite3::createFunction(string name, mixed callback [, int argcount])
+/* {{{ proto bool SQLite3::createFunction(string name, mixed callback [, int argcount, int flags])
    Allows registration of a PHP function as a SQLite UDF that can be called within SQL statements. */
 PHP_METHOD(sqlite3, createFunction)
 {
@@ -903,11 +903,12 @@ PHP_METHOD(sqlite3, createFunction)
 	zval *callback_func;
 	zend_string *callback_name;
 	zend_long sql_func_num_args = -1;
+	zend_long flags = 0;
 	db_obj = Z_SQLITE3_DB_P(object);
 
 	SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|l", &sql_func, &sql_func_len, &callback_func, &sql_func_num_args) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|ll", &sql_func, &sql_func_len, &callback_func, &sql_func_num_args, &flags) == FAILURE) {
 		return;
 	}
 
@@ -924,7 +925,7 @@ PHP_METHOD(sqlite3, createFunction)
 
 	func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
 
-	if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) {
+	if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, flags | SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) {
 		func->func_name = estrdup(sql_func);
 
 		ZVAL_COPY(&func->func, callback_func);
@@ -1894,6 +1895,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_createfunction, 0, 0, 2)
 	ZEND_ARG_INFO(0, name)
 	ZEND_ARG_INFO(0, callback)
 	ZEND_ARG_INFO(0, argument_count)
+	ZEND_ARG_INFO(0, flags)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_createaggregate, 0, 0, 3)
@@ -2281,6 +2283,8 @@ PHP_MINIT_FUNCTION(sqlite3)
 	REGISTER_LONG_CONSTANT("SQLITE3_OPEN_READWRITE", SQLITE_OPEN_READWRITE, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("SQLITE3_OPEN_CREATE", SQLITE_OPEN_CREATE, CONST_CS | CONST_PERSISTENT);
 
+	REGISTER_LONG_CONSTANT("SQLITE3_DETERMINISTIC", SQLITE_DETERMINISTIC, CONST_CS | CONST_PERSISTENT);
+
 	return SUCCESS;
 }
 /* }}} */
diff --git a/ext/sqlite3/tests/sqlite3_37_createfunction_flags.phpt b/ext/sqlite3/tests/sqlite3_37_createfunction_flags.phpt
new file mode 100644
index 0000000..31fd42b
--- /dev/null
+++ b/ext/sqlite3/tests/sqlite3_37_createfunction_flags.phpt
@@ -0,0 +1,29 @@
+--TEST--
+SQLite3::createFunction - Test with flags
+--SKIPIF--
+<?php require_once(__DIR__ . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+require_once(__DIR__ . '/new_db.inc');
+
+$func = 'strtoupper';
+var_dump($db->createfunction($func, $func, 1, SQLITE3_DETERMINISTIC));
+var_dump($db->querySingle('SELECT strtoupper("test")'));
+
+$func2 = 'strtolower';
+var_dump($db->createfunction($func2, $func2, 1, SQLITE3_DETERMINISTIC));
+var_dump($db->querySingle('SELECT strtolower("TEST")'));
+
+var_dump($db->createfunction($func, $func2, 1, SQLITE3_DETERMINISTIC));
+var_dump($db->querySingle('SELECT strtoupper("tEst")'));
+
+
+?>
+--EXPECTF--
+bool(true)
+string(4) "TEST"
+bool(true)
+string(4) "test"
+bool(true)
+string(4) "test"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.