Skip to content

Commit 6498785

Browse files
Merge pull request #155 from newrelic/dev
Merge 9.17.1 changes from dev to main
2 parents adbdca6 + 8375b36 commit 6498785

File tree

7 files changed

+155
-81
lines changed

7 files changed

+155
-81
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ src/newrelic/infinite_tracing/com_newrelic_trace_v1/v1.pb.go: protocol/infinite_
314314

315315
.PHONY: integration
316316
integration: Makefile daemon lasp-test-all
317-
for PHP in $${PHPS:-7.4 7.3 7.2 7.1 7.0 5.6 5.5 5.4 5.3}; do \
317+
for PHP in $${PHPS:-8.0 7.4 7.3 7.2 7.1 7.0 5.6 5.5 5.4 5.3}; do \
318318
echo; echo "# PHP=$${PHP}"; \
319319
env NRLAMP_PHP=$${PHP} bin/integration_runner $(INTEGRATION_ARGS) || exit 1; \
320320
echo "# PHP=$${PHP}"; \
@@ -379,7 +379,7 @@ lasp-test: daemon
379379
if [ ! $(SUITE_LASP) ]; then echo "USAGE: make lasp-test SUITE_LASP=suite-most-secure"; exit 1; fi
380380
if [ "$(LICENSE_lasp_$(subst -,_,$(SUITE_LASP)))" = "" ] ; then echo "Missing license for $(SUITE_LASP)"; exit 1; fi
381381
if [ ! -d "tests/lasp/$(SUITE_LASP)" ]; then echo "No such suite in tests/lasp folder"; exit 1; fi
382-
for PHP in $${PHPS:-7.4 7.3 7.2 7.1 7.0 5.6 5.5 5.4 5.3}; do \
382+
for PHP in $${PHPS:-8.0 7.4 7.3 7.2 7.1 7.0 5.6 5.5 5.4 5.3}; do \
383383
echo; echo "# PHP=$${PHP}"; \
384384
NRLAMP_PHP=$${PHP} bin/integration_runner $(INTEGRATION_ARGS) -loglevel debug \
385385
-license $(LICENSE_lasp_$(subst -,_,$(SUITE_LASP))) \

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9.17.0
1+
9.17.1

agent/php_internal_instrument.c

Lines changed: 42 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -749,22 +749,50 @@ NR_INNER_WRAPPER(mysqli_options) {
749749
}
750750
}
751751

752+
static void nr_php_instrument_datastore_operation_call(
753+
const nrinternalfn_t* nr_wrapper,
754+
nr_datastore_t datastore,
755+
const char* operation,
756+
nr_datastore_instance_t* instance,
757+
INTERNAL_FUNCTION_PARAMETERS) {
758+
int zcaught = 0;
759+
nr_segment_t* segment = NULL;
760+
nr_segment_datastore_params_t params = {
761+
.datastore = {
762+
.type = datastore,
763+
},
764+
.operation = nr_strdup(operation),
765+
.instance = instance,
766+
.callbacks = {
767+
.backtrace = nr_php_backtrace_callback,
768+
},
769+
};
770+
771+
segment = nr_segment_start(NRPRG(txn), NULL, NULL);
772+
zcaught = nr_zend_call_old_handler(nr_wrapper->oldhandler,
773+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
774+
775+
nr_segment_datastore_end(&segment, &params);
776+
777+
nr_free(params.operation);
778+
779+
if (zcaught) {
780+
zend_bailout();
781+
/* NOTREACHED */
782+
}
783+
}
784+
752785
/*
753786
* Handle
754787
* bool mysqli_commit ( object $link [, int $flags=0, string $name] )
755788
* bool mysqli::commit ( [, int $flags=0, string $name] )
756789
*/
757790
NR_INNER_WRAPPER(mysqli_commit) {
758791
zval* mysqli_obj = NULL;
759-
nr_segment_t* segment = NULL;
760792
nr_datastore_instance_t* instance = NULL;
761-
nr_explain_plan_t* plan = NULL;
762793
char* name = NULL;
763-
char* sqlstr = NULL;
764-
nr_string_len_t sqlstrlen;
765794
zend_long flags = 0;
766795
nr_string_len_t name_len = 0;
767-
int zcaught = 0;
768796

769797
if (FAILURE
770798
== zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
@@ -780,35 +808,9 @@ NR_INNER_WRAPPER(mysqli_commit) {
780808
mysqli_obj = NR_PHP_INTERNAL_FN_THIS();
781809
}
782810
}
783-
784-
if (NULL != name) {
785-
sqlstr = nr_formatf("%s %s", "COMMIT", name);
786-
} else {
787-
sqlstr = nr_formatf("%s", "COMMIT");
788-
}
789-
sqlstrlen = nr_strlen(sqlstr);
790-
791-
segment = nr_segment_start(NRPRG(txn), NULL, NULL);
792-
793-
if (nrlikely(NULL != segment)) {
794-
/*
795-
* Set the stop time now so that we don't include the explain plan time.
796-
*/
797-
segment->stop_time = nr_txn_now_rel(NRPRG(txn));
798-
instance = nr_php_mysqli_retrieve_datastore_instance(mysqli_obj TSRMLS_CC);
799-
800-
nr_php_txn_end_segment_sql(&segment, sqlstr, sqlstrlen, plan,
801-
NR_DATASTORE_MYSQL, instance TSRMLS_CC);
802-
803-
nr_explain_plan_destroy(&plan);
804-
805-
}
806-
807-
nr_free(sqlstr);
808-
if (zcaught) {
809-
zend_bailout();
810-
/* NOTREACHED */
811-
}
811+
nr_php_instrument_datastore_operation_call(nr_wrapper, NR_DATASTORE_MYSQL,
812+
"commit", instance,
813+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
812814
}
813815

814816
/*
@@ -1445,39 +1447,6 @@ NR_INNER_WRAPPER(mysqli_stmt_prepare) {
14451447
}
14461448
}
14471449

1448-
static void nr_php_instrument_datastore_operation_call(
1449-
const nrinternalfn_t* nr_wrapper,
1450-
nr_datastore_t datastore,
1451-
const char* operation,
1452-
nr_datastore_instance_t* instance,
1453-
INTERNAL_FUNCTION_PARAMETERS) {
1454-
int zcaught = 0;
1455-
nr_segment_t* segment = NULL;
1456-
nr_segment_datastore_params_t params = {
1457-
.datastore = {
1458-
.type = datastore,
1459-
},
1460-
.operation = nr_strdup(operation),
1461-
.instance = instance,
1462-
.callbacks = {
1463-
.backtrace = nr_php_backtrace_callback,
1464-
},
1465-
};
1466-
1467-
segment = nr_segment_start(NRPRG(txn), NULL, NULL);
1468-
zcaught = nr_zend_call_old_handler(nr_wrapper->oldhandler,
1469-
INTERNAL_FUNCTION_PARAM_PASSTHRU);
1470-
1471-
nr_segment_datastore_end(&segment, &params);
1472-
1473-
nr_free(params.operation);
1474-
1475-
if (zcaught) {
1476-
zend_bailout();
1477-
/* NOTREACHED */
1478-
}
1479-
}
1480-
14811450
/*
14821451
* Handle
14831452
* bool memcache_xxx( ... )
@@ -2698,11 +2667,13 @@ NR_INNER_WRAPPER(curl_multi_exec) {
26982667
int rv = FAILURE;
26992668

27002669
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO /* PHP 8.0+ */
2701-
rv = zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
2702-
"ol", &curlres, &still_running);
2670+
rv = zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
2671+
ZEND_NUM_ARGS() TSRMLS_CC, "ol", &curlres,
2672+
&still_running);
27032673
#else
2704-
rv = zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
2705-
"rl", &curlres, &still_running);
2674+
rv = zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
2675+
ZEND_NUM_ARGS() TSRMLS_CC, "rl", &curlres,
2676+
&still_running);
27062677
#endif /* PHP 8.0+ */
27072678

27082679
if (SUCCESS != rv) {

agent/php_pdo.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ int nr_php_pdo_rebind_apply_parameter(struct pdo_bound_param_data* param,
130130
zval* type = nr_php_zval_alloc();
131131
zval* retval = NULL;
132132

133-
#ifdef PHP7
133+
#if ZEND_MODULE_API_NO >= ZEND_7_0_X_API_NO /* PHP 7.0+ */
134134
value = &param->parameter;
135135
#else
136136
value = param->parameter;
137-
#endif /* PHP7 */
137+
#endif /* PHP 7.0+ */
138138

139139
if (nr_php_zend_hash_key_is_string(hash_key)) {
140140
/*
@@ -152,6 +152,16 @@ int nr_php_pdo_rebind_apply_parameter(struct pdo_bound_param_data* param,
152152

153153
ZVAL_LONG(type, param->param_type);
154154

155+
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO /* PHP 8.0+ */
156+
/*
157+
* Create a reference to value to prevent PHP 8 from
158+
* emitting a warning.
159+
*/
160+
if (!Z_ISREF_P(value)) {
161+
Z_TRY_ADDREF_P(value);
162+
ZVAL_NEW_REF(value, value);
163+
}
164+
#endif
155165
retval = nr_php_call(stmt, "bindParam", key, value, type);
156166

157167
nr_php_zval_free(&key);

axiom/nr_version.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
* Here's a list:
2626
* https://en.wikipedia.org/wiki/List_of_colors_(compact)
2727
*
28-
* ube (9.14)
29-
* vanilla (9.15)
30-
* watermelon (9.16)
31-
* xigua (9.17)
28+
* ube 29Oct2020 (9.14)
29+
* vanilla 07Dec2020 (9.15)
30+
* watermelon 25Jan2021 (9.16)
31+
* xigua 21Apr2021 (9.17)
3232
*/
3333
#define NR_CODENAME "xigua"
3434

docs/development.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ _(most operating systems package these with `-dev` or `-devel` suffixes)_
5959

6060
### PHP
6161

62-
The PHP agent supports PHP versions `5.3`, `5.4`, `5.5`, `5.6`, `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, and `8.0`.
62+
The PHP agent supports PHP versions `5.5`, `5.6`, `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, and `8.0`.
6363

6464
## Build the PHP Agent
6565

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
/*
3+
* Copyright 2020 New Relic Corporation. All rights reserved.
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*DESCRIPTION
8+
The agent should record a slow sql trace when a prepared
9+
statment with a parameter is executed via PDOStatement::execute()
10+
exceeds the explain threshold.
11+
*/
12+
13+
/*SKIPIF
14+
<?php require('skipif_mysql.inc');
15+
*/
16+
17+
/*INI
18+
newrelic.datastore_tracer.database_name_reporting.enabled = 0
19+
newrelic.datastore_tracer.instance_reporting.enabled = 0
20+
newrelic.transaction_tracer.explain_enabled = true
21+
newrelic.transaction_tracer.explain_threshold = 0
22+
newrelic.transaction_tracer.record_sql = "obfuscated"
23+
*/
24+
25+
/*EXPECT
26+
ok - execute prepared statement with a param
27+
*/
28+
29+
/*EXPECT_SLOW_SQLS
30+
[
31+
[
32+
[
33+
"OtherTransaction/php__FILE__",
34+
"<unknown>",
35+
"?? SQL id",
36+
"select * from tables where table_name = ? limit ?;",
37+
"Datastore/statement/MySQL/tables/select",
38+
1,
39+
"?? total time",
40+
"?? min time",
41+
"?? max time",
42+
{
43+
"backtrace": [
44+
" in PDOStatement::execute called at __FILE__ (??)",
45+
" in test_prepared_statement called at __FILE__ (??)"
46+
],
47+
"explain_plan": [
48+
[
49+
"id",
50+
"select_type",
51+
"table",
52+
"type",
53+
"possible_keys",
54+
"key",
55+
"key_len",
56+
"ref",
57+
"rows",
58+
"Extra"
59+
],
60+
[
61+
[
62+
"1",
63+
"SIMPLE",
64+
"tables",
65+
"ALL",
66+
null,
67+
"TABLE_NAME",
68+
null,
69+
null,
70+
"??",
71+
"??"
72+
]
73+
]
74+
]
75+
}
76+
]
77+
]
78+
]
79+
*/
80+
81+
require_once(realpath (dirname ( __FILE__ )) . '/../../include/tap.php');
82+
require_once(realpath (dirname ( __FILE__ )) . '/pdo.inc');
83+
84+
function test_prepared_statement() {
85+
global $PDO_MYSQL_DSN, $MYSQL_USER, $MYSQL_PASSWD;
86+
87+
$conn = new PDO($PDO_MYSQL_DSN, $MYSQL_USER, $MYSQL_PASSWD);
88+
$stmt = $conn->prepare('select * from tables where table_name = ? limit 1;');
89+
$stmt->bindValue(1, "missing");
90+
tap_assert($stmt->execute(), 'execute prepared statement with a param');
91+
}
92+
93+
test_prepared_statement();

0 commit comments

Comments
 (0)