summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BitKeeper/etc/collapsed8
-rw-r--r--mysql-test/r/udf.result35
-rw-r--r--mysql-test/t/udf.test39
-rw-r--r--sql/item_func.cc62
-rw-r--r--sql/udf_example.c30
5 files changed, 146 insertions, 28 deletions
diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed
index 311c3813abf..357e2c84566 100644
--- a/BitKeeper/etc/collapsed
+++ b/BitKeeper/etc/collapsed
@@ -15,3 +15,11 @@
45214442pBGT9KuZEGixBH71jTzbOA
45214a07hVsIGwvwa-WrO-jpeaSwVw
452a92d0-31-8wSzSfZi165fcGcXPA
+454bb488ijVLOUK_GFjcoISE0GxPUA
+454bb9a8AwlGRC_wWLS2sNMoRBMRGw
+454c946ciQoR4dfTBZ0RTBmGJKp6lw
+454f6e7eAnfLD9OCbGr5X9KiKvfKcQ
+454f704bJiJy0_Nx2drY9P5kK3uOzg
+454fa71cxshxszXJQYa9jbo0-_hAHw
+4550b0ceIcozdgQhWFUTAtWkN196lA
+4558b3d73Cxjlb7Wv1oytdSTthxDfw
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result
index a552282fece..6b72dcd4f30 100644
--- a/mysql-test/r/udf.result
+++ b/mysql-test/r/udf.result
@@ -115,3 +115,38 @@ DROP FUNCTION sequence;
DROP FUNCTION lookup;
DROP FUNCTION reverse_lookup;
DROP FUNCTION avgcost;
+CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
+select
+is_const(3) as const,
+is_const(3.14) as const,
+is_const('fnord') as const,
+is_const(2+3) as const,
+is_const(rand()) as 'nc rand()',
+is_const(sin(3.14)) as const,
+is_const(upper('test')) as const;
+const const const const nc rand() const const
+const const const const not const const const
+create table bug18761 (n int);
+insert into bug18761 values (null),(2);
+select
+is_const(3) as const,
+is_const(3.14) as const,
+is_const('fnord') as const,
+is_const(2+3) as const,
+is_const(2+n) as 'nc 2+n ',
+is_const(sin(n)) as 'nc sin(n)',
+is_const(sin(3.14)) as const,
+is_const(upper('test')) as const,
+is_const(rand()) as 'nc rand()',
+is_const(n) as 'nc n ',
+is_const(is_const(n)) as 'nc ic?(n)',
+is_const(is_const('c')) as const
+from
+bug18761;
+const const const const nc 2+n nc sin(n) const const nc rand() nc n nc ic?(n) const
+const const const const not const not const const const not const not const not const const
+const const const const not const not const const const not const not const not const const
+drop table bug18761;
+select is_const((1,2,3));
+ERROR 21000: Operand should contain 1 column(s)
+drop function if exists is_const;
diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test
index 96e559f5c05..c62d7829b05 100644
--- a/mysql-test/t/udf.test
+++ b/mysql-test/t/udf.test
@@ -143,4 +143,41 @@ DROP FUNCTION lookup;
DROP FUNCTION reverse_lookup;
DROP FUNCTION avgcost;
-
+#
+# Bug#18761: constant expression as UDF parameters not passed in as constant
+#
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION is_const RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
+
+select
+ is_const(3) as const,
+ is_const(3.14) as const,
+ is_const('fnord') as const,
+ is_const(2+3) as const,
+ is_const(rand()) as 'nc rand()',
+ is_const(sin(3.14)) as const,
+ is_const(upper('test')) as const;
+
+create table bug18761 (n int);
+insert into bug18761 values (null),(2);
+select
+ is_const(3) as const,
+ is_const(3.14) as const,
+ is_const('fnord') as const,
+ is_const(2+3) as const,
+ is_const(2+n) as 'nc 2+n ',
+ is_const(sin(n)) as 'nc sin(n)',
+ is_const(sin(3.14)) as const,
+ is_const(upper('test')) as const,
+ is_const(rand()) as 'nc rand()',
+ is_const(n) as 'nc n ',
+ is_const(is_const(n)) as 'nc ic?(n)',
+ is_const(is_const('c')) as const
+from
+ bug18761;
+drop table bug18761;
+
+--error 1241
+select is_const((1,2,3));
+
+drop function if exists is_const;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 4a069e662f9..38c395cca10 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2700,39 +2700,47 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
char *to=num_buffer;
for (uint i=0; i < arg_count; i++)
{
- f_args.args[i]=0;
+ /*
+ For a constant argument i, args->args[i] points to the argument value.
+ For non-constant, args->args[i] is NULL.
+ */
+ f_args.args[i]= NULL; /* Non-const unless updated below. */
+
f_args.lengths[i]= arguments[i]->max_length;
f_args.maybe_null[i]= (char) arguments[i]->maybe_null;
f_args.attributes[i]= arguments[i]->name;
f_args.attribute_lengths[i]= arguments[i]->name_length;
- switch(arguments[i]->type()) {
- case Item::STRING_ITEM: // Constant string !
+ if (arguments[i]->const_item())
{
- String *res=arguments[i]->val_str(&buffers[i]);
- if (arguments[i]->null_value)
- continue;
- f_args.args[i]= (char*) res->ptr();
- break;
- }
- case Item::INT_ITEM:
- *((longlong*) to) = arguments[i]->val_int();
- if (!arguments[i]->null_value)
- {
- f_args.args[i]=to;
- to+= ALIGN_SIZE(sizeof(longlong));
- }
- break;
- case Item::REAL_ITEM:
- *((double*) to)= arguments[i]->val_real();
- if (!arguments[i]->null_value)
- {
- f_args.args[i]=to;
- to+= ALIGN_SIZE(sizeof(double));
- }
- break;
- default: // Skip these
- break;
+ if (arguments[i]->null_value)
+ continue;
+
+ switch (arguments[i]->result_type())
+ {
+ case STRING_RESULT:
+ case DECIMAL_RESULT:
+ {
+ String *res= arguments[i]->val_str(&buffers[i]);
+ f_args.args[i]= (char*) res->ptr();
+ break;
+ }
+ case INT_RESULT:
+ *((longlong*) to)= arguments[i]->val_int();
+ f_args.args[i]= to;
+ to+= ALIGN_SIZE(sizeof(longlong));
+ break;
+ case REAL_RESULT:
+ *((double*) to)= arguments[i]->val_real();
+ f_args.args[i]= to;
+ to+= ALIGN_SIZE(sizeof(double));
+ break;
+ case ROW_RESULT:
+ default:
+ // This case should never be chosen
+ DBUG_ASSERT(0);
+ break;
+ }
}
}
thd->net.last_error[0]=0;
diff --git a/sql/udf_example.c b/sql/udf_example.c
index 2fa7474eb16..a4f7eddd302 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -165,6 +165,9 @@ void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error
void avgcost_clear( UDF_INIT* initid, char* is_null, char *error );
void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
double avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
+my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
+char *is_const(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long
+ *length, char *is_null, char *error);
/*************************************************************************
@@ -1075,4 +1078,31 @@ char *myfunc_argument_name(UDF_INIT *initid __attribute__((unused)),
return result;
}
+
+
+my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ if (args->arg_count != 1)
+ {
+ strmov(message, "IS_CONST accepts only one argument");
+ return 1;
+ }
+ initid->ptr= (args->args[0] != NULL) ? 1 : 0;
+ return 0;
+}
+
+char * is_const(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long
+ *length, char *is_null, char *error)
+{
+ if (initid->ptr != 0) {
+ sprintf(result, "const");
+ } else {
+ sprintf(result, "not const");
+ }
+ *is_null= 0;
+ *length= strlen(result);
+ return result;
+}
+
+
#endif /* HAVE_DLOPEN */