Changeset: 79b522cb05a2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=79b522cb05a2
Added Files:
        sql/test/BugTracker-2009/Tests/AVG_of_SQRT.SF-2757642.sql
        
sql/test/BugTracker-2016/Tests/min-max-uuid-column-wrong-results.Bug-3953.sql
        
sql/test/BugTracker-2017/Tests/sqlitelogictest-cast-decimal.Bug-6445.stable.err
        
sql/test/BugTracker-2017/Tests/sqlitelogictest-cast-decimal.Bug-6445.stable.out
        sql/test/BugTracker-2017/Tests/sqlsmith.Bug-6449.sql
        sql/test/BugTracker-2017/Tests/sqlsmith.Bug-6449.stable.err
        sql/test/BugTracker-2017/Tests/sqlsmith.Bug-6449.stable.out
        sql/test/Tests/fsum.sql
        sql/test/Tests/fsum.stable.err
        sql/test/Tests/fsum.stable.out
        sql/test/Tests/fsum1.sql.src
        sql/test/Tests/fsum1.stable.err.src
        sql/test/Tests/fsum1.stable.out.src
        sql/test/mergetables/Tests/sqlsmith.Bug-6451.sql
        sql/test/mergetables/Tests/sqlsmith.Bug-6451.stable.err
        sql/test/mergetables/Tests/sqlsmith.Bug-6451.stable.out
        sql/test/mergetables/Tests/sqlsmith.Bug-6453.sql
        sql/test/mergetables/Tests/sqlsmith.Bug-6453.stable.err
        sql/test/mergetables/Tests/sqlsmith.Bug-6453.stable.out
        sql/test/mergetables/Tests/sqlsmith.Bug-6455.sql
        sql/test/mergetables/Tests/sqlsmith.Bug-6455.stable.err
        sql/test/mergetables/Tests/sqlsmith.Bug-6455.stable.out
Removed Files:
        sql/test/BugTracker-2009/Tests/AVG_of_SQRT.SF-2757642.SQL.py
        sql/test/BugTracker-2011/Tests/and-power.Bug-3013.stable.out.int128
        sql/test/BugTracker-2016/Tests/data-uuid.csv.bz2
        
sql/test/BugTracker-2016/Tests/min-max-uuid-column-wrong-results.Bug-3953.sql.in
Modified Files:
        MonetDB.spec
        NT/monetdb_config.h.in
        buildtools/selinux/monetdb.te
        clients/Tests/exports.stable.out
        configure.ag
        gdk/ChangeLog
        gdk/ChangeLog.Jul2017
        gdk/gdk.h
        gdk/gdk_aggr.c
        gdk/gdk_align.c
        gdk/gdk_atoms.c
        gdk/gdk_atoms.h
        gdk/gdk_bat.c
        gdk/gdk_batop.c
        gdk/gdk_bbp.c
        gdk/gdk_calc.c
        gdk/gdk_calc_compare.h
        gdk/gdk_calc_private.h
        gdk/gdk_firstn.c
        gdk/gdk_group.c
        gdk/gdk_hash.c
        gdk/gdk_imprints.c
        gdk/gdk_join.c
        gdk/gdk_logger.c
        gdk/gdk_logger.h
        gdk/gdk_orderidx.c
        gdk/gdk_project.c
        gdk/gdk_qsort.c
        gdk/gdk_search.c
        gdk/gdk_select.c
        gdk/gdk_ssort.c
        gdk/gdk_unique.c
        gdk/gdk_utils.c
        gdk/gdk_value.c
        geom/monetdb5/geom.c
        geom/monetdb5/geom.h
        monetdb5/extras/rapi/converters.c.h
        monetdb5/mal/mal_atom.c
        monetdb5/mal/mal_authorize.c
        monetdb5/mal/mal_builder.c
        monetdb5/mal/mal_debugger.c
        monetdb5/mal/mal_function.c
        monetdb5/mal/mal_instruction.c
        monetdb5/mal/mal_interpreter.c
        monetdb5/mal/mal_parser.c
        monetdb5/modules/atoms/color.c
        monetdb5/modules/atoms/color.h
        monetdb5/modules/atoms/json.c
        monetdb5/modules/atoms/mtime.c
        monetdb5/modules/atoms/str.c
        monetdb5/modules/kernel/algebra.c
        monetdb5/modules/kernel/batcolor.c
        monetdb5/modules/kernel/batmmath.c
        monetdb5/modules/kernel/microbenchmark.c
        monetdb5/modules/kernel/mmath.c
        monetdb5/modules/kernel/mmath.h
        monetdb5/modules/mal/batcalc.c
        monetdb5/modules/mal/calc.c
        monetdb5/modules/mal/clients.c
        monetdb5/modules/mal/iterator.c
        monetdb5/modules/mal/language.c
        monetdb5/modules/mal/mal_io.c
        monetdb5/modules/mal/mkey.c
        monetdb5/modules/mal/pcre.c
        monetdb5/modules/mal/remote.c
        monetdb5/modules/mal/tablet.c
        monetdb5/optimizer/opt_mergetable.c
        monetdb5/optimizer/opt_multiplex.c
        monetdb5/optimizer/opt_remap.c
        sql/ChangeLog
        sql/backends/monet5/LSST/lsst.c
        sql/backends/monet5/UDF/cudf/udf_impl.h
        sql/backends/monet5/UDF/pyapi/conversion.c
        sql/backends/monet5/UDF/pyapi/convert_loops.h
        sql/backends/monet5/UDF/pyapi/emit.c
        sql/backends/monet5/generator/generator.c
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_cast_impl_down_from_flt.h
        sql/backends/monet5/sql_cast_impl_int.h
        sql/backends/monet5/sql_cast_impl_up_to_flt.h
        sql/backends/monet5/sql_cat.c
        sql/backends/monet5/sql_fround.c
        sql/backends/monet5/sql_fround_impl.h
        sql/backends/monet5/sql_gencode.c
        sql/backends/monet5/sql_result.c
        sql/backends/monet5/sql_round.c
        sql/backends/monet5/sql_round_impl.h
        sql/backends/monet5/sql_scenario.c
        sql/backends/monet5/sql_user.c
        sql/backends/monet5/vaults/bam/bam_lib.c
        sql/backends/monet5/vaults/fits/fits.c
        sql/backends/monet5/vaults/lidar/lidar.c
        sql/backends/monet5/vaults/netcdf/netcdf.c
        sql/backends/monet5/vaults/shp/shp.c
        sql/server/rel_dump.c
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_select.c
        sql/server/rel_sequence.c
        sql/server/rel_updates.c
        sql/server/sql_atom.c
        sql/server/sql_mvc.c
        sql/server/sql_parser.h
        sql/server/sql_parser.y
        sql/server/sql_privileges.c
        sql/server/sql_scan.c
        sql/storage/bat/bat_storage.c
        sql/storage/bat/bat_table.c
        sql/storage/store.c
        sql/storage/store_dependency.c
        sql/test/BugTracker-2009/Tests/AVG_of_SQRT.SF-2757642.stable.out
        sql/test/BugTracker-2011/Tests/and-power.Bug-3013.stable.out
        sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.err
        sql/test/BugTracker-2016/Tests/All
        sql/test/BugTracker-2017/Tests/All
        sql/test/BugTracker-2017/Tests/double-groupby-column.Bug-6207.sql
        sql/test/BugTracker-2017/Tests/double-groupby-column.Bug-6207.stable.out
        
sql/test/BugTracker-2017/Tests/extract_quarter_week_from_date.Bug-3831.sql
        
sql/test/BugTracker-2017/Tests/insert_into_multiple_subqueries.Bug-6448.sql
        
sql/test/BugTracker-2017/Tests/insert_into_multiple_subqueries.Bug-6448.stable.err
        
sql/test/BugTracker-2017/Tests/insert_into_multiple_subqueries.Bug-6448.stable.out
        sql/test/BugTracker-2017/Tests/table_returning_with.Bug-6444.sql
        sql/test/BugTracker-2017/Tests/table_returning_with.Bug-6444.stable.err
        sql/test/BugTracker-2017/Tests/table_returning_with.Bug-6444.stable.out
        sql/test/BugTracker/Tests/drop_schema_crash.SF-1504794.stable.err
        sql/test/BugTracker/Tests/set_a_new_user_password.SF-1844050.stable.err
        sql/test/Dependencies/Tests/Dependencies.stable.err
        sql/test/Tests/All
        sql/test/emptydb-upgrade-chain-hge/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade-hge/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade/Tests/upgrade.stable.out.int128
        sql/test/mergetables/Tests/All
        sql/test/testdb-upgrade-chain-hge/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade-hge/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade/Tests/upgrade.stable.out.int128
        testing/ChangeLog
        testing/Mtest.py.in
        tools/merovingian/daemon/merovingian.c
Branch: data-vaults
Log Message:

Merge with default

Resolve conflicts by using is_oid_nil macro


diffs (truncated from 33134 to 300 lines):

diff --git a/MonetDB.spec b/MonetDB.spec
--- a/MonetDB.spec
+++ b/MonetDB.spec
@@ -885,7 +885,7 @@ developer, but if you do want to test, t
 
 %if %{?rhel:0}%{!?rhel:1} || 0%{?rhel} >= 7
 %package selinux
-Summary: MonetDB - Monet Database Management System
+Summary: SELinux policy files for MonetDB
 Group: Applications/Databases
 %if "%{_selinux_policy_version}" != ""
 Requires:       selinux-policy >= %{_selinux_policy_version}
@@ -1002,6 +1002,11 @@ make %{?_smp_mflags}
 
 %if %{?rhel:0}%{!?rhel:1} || 0%{?rhel} >= 7
 cd buildtools/selinux
+%if 0%{?fedora} < 27
+# no `map' policy available before Fedora 27
+sed -i '/map/d' monetdb.te
+%endif
+
 for selinuxvariant in %{selinux_variants}
 do
   make NAME=${selinuxvariant} -f /usr/share/selinux/devel/Makefile
@@ -1041,6 +1046,9 @@ done
 %postun -p /sbin/ldconfig
 
 %changelog
+* Sun Nov  5 2017 Sjoerd Mullender <sjo...@acm.org> - 11.27.9-20171105
+- BZ#6460 - selinux doen't allow mmap
+
 * Mon Oct 23 2017 Sjoerd Mullender <sjo...@acm.org> - 11.27.9-20171023
 - Rebuilt.
 - BZ#6207: identifier ambiguous when grouping and selecting the same
diff --git a/NT/monetdb_config.h.in b/NT/monetdb_config.h.in
--- a/NT/monetdb_config.h.in
+++ b/NT/monetdb_config.h.in
@@ -33,6 +33,12 @@
 #define _CRT_SECURE_NO_DEPRECATE 1
 #endif
 
+/* include Intel's mathimf.h early, before any other include files
+ * might try to include math.h */
+#ifdef __INTEL_COMPILER
+#include <mathimf.h>
+#endif
+
 #include <malloc.h>
 
 #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
@@ -160,14 +166,6 @@
 /* Define if the fits module is to be enabled */
 /* #undef HAVE_FITS */
 
-/* Define to 1 if you have the `fpclass' function. */
-#define HAVE_FPCLASS 1         /* uses _fpclass, see mmath.c */
-
-/* Define to 1 if you have the `fpclassify' function. */
-#if defined(_MSC_VER) && _MSC_VER > 1600
-#define HAVE_FPCLASSIFY 1
-#endif
-
 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
 /* #undef HAVE_FSEEKO */
 
diff --git a/buildtools/selinux/monetdb.te b/buildtools/selinux/monetdb.te
--- a/buildtools/selinux/monetdb.te
+++ b/buildtools/selinux/monetdb.te
@@ -1,4 +1,4 @@
-policy_module(monetdb, 0.1)
+policy_module(monetdb, 0.2)
 # The above line declares that this file is a SELinux policy file. Its
 # name is monetdb, so the file should be saved as monetdb.te
 
@@ -39,6 +39,7 @@ manage_files_pattern(mserver5_t, mserver
 manage_dirs_pattern(mserver5_t, mserver5_db_t, mserver5_db_t)
 manage_files_pattern(monetdbd_t, mserver5_db_t, mserver5_db_t)
 manage_dirs_pattern(monetdbd_t, mserver5_db_t, mserver5_db_t)
+allow mserver5_t mserver5_db_t:file { map };
 
 # the context used for the configuration files
 type monetdbd_etc_t;
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -10,7 +10,6 @@ void ALIGNsetH(BAT *b1, BAT *b2);
 void ALIGNsetT(BAT *b1, BAT *b2);
 int ALIGNsynced(BAT *b1, BAT *b2);
 int ATOMallocate(const char *nme);
-int ATOMcmp(int id, const void *v_1, const void *v_2);
 ptr ATOMdup(int id, const void *val);
 bte ATOMelmshift(int sz);
 char *ATOMformat(int id, const void *val);
@@ -378,7 +377,7 @@ const bte bte_nil;
 int closedir(DIR *dir);
 ssize_t dblFromStr(const char *src, size_t *len, dbl **dst);
 ssize_t dblToStr(str *dst, size_t *len, const dbl *src);
-const dbl dbl_nil;
+NANCONST dbl dbl_nil;
 char *dirname(char *path);
 int dlclose(void *handle);
 char *dlerror(void);
@@ -388,7 +387,7 @@ size_t escapedStr(char *dst, const char 
 size_t escapedStrlen(const char *src, const char *sep1, const char *sep2, int 
quote);
 ssize_t fltFromStr(const char *src, size_t *len, flt **dst);
 ssize_t fltToStr(str *dst, size_t *len, const flt *src);
-const flt flt_nil;
+NANCONST flt flt_nil;
 geomcatalogfix_fptr geomcatalogfix_get(void);
 void geomcatalogfix_set(geomcatalogfix_fptr);
 geomsqlfix_fptr geomsqlfix_get(void);
diff --git a/configure.ag b/configure.ag
--- a/configure.ag
+++ b/configure.ag
@@ -2731,8 +2731,6 @@ AC_CHECK_FUNCS([\
        fabsf \
        fallocate \
        fcntl \
-       fpclass \
-       fpclassify \
        fsync \
        ftime \
        getexecname \
diff --git a/gdk/ChangeLog b/gdk/ChangeLog
--- a/gdk/ChangeLog
+++ b/gdk/ChangeLog
@@ -1,6 +1,10 @@
 # ChangeLog file for MonetDB
 # This file is updated with Maddlog
 
+* Tue Nov  7 2017 Sjoerd Mullender <sjo...@acm.org>
+- The NIL representation of the internal flt and dbl types was changed
+  from the smallest representable finite value to NaN (not-a-number).
+
 * Mon Sep 18 2017 Sjoerd Mullender <sjo...@acm.org>
 - Changed the interface of ATOMformat and VALformat: they now return a
   pointer to the allocated string.
diff --git a/gdk/ChangeLog.Jul2017 b/gdk/ChangeLog.Jul2017
--- a/gdk/ChangeLog.Jul2017
+++ b/gdk/ChangeLog.Jul2017
@@ -1,3 +1,10 @@
 # ChangeLog file for MonetDB
 # This file is updated with Maddlog
 
+* Mon Oct 30 2017 Sjoerd Mullender <sjo...@acm.org>
+- Reimplemented summing of a column of floating point (flt and dbl)
+  values.  The old code could give wildly inaccurate results when adding
+  up lots and lots of values due to lack of precision.  Try SELECT sum(c)
+  FROM t; where t is 100,000,000 rows, c is of type REAL and all values
+  are equal to 1.1.  (The old code returned 33554432 instead of 1.1e8.)
+
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -859,7 +859,8 @@ typedef struct {
 #define GDKLIBRARY_NOKEY       061034  /* nokey values can't be trusted */
 #define GDKLIBRARY_BADEMPTY    061035  /* possibility of duplicate empty str */
 #define GDKLIBRARY_TALIGN      061036  /* talign field in BBP.dir */
-#define GDKLIBRARY             061037
+#define GDKLIBRARY_NIL_NAN     061037  /* flt/dbl NIL not represented by NaN */
+#define GDKLIBRARY             061040
 
 typedef struct BAT {
        /* static bat properties */
@@ -1293,13 +1294,13 @@ gdk_export BUN ORDERfndlast(BAT *b, cons
 gdk_export BUN BUNfnd(BAT *b, const void *right);
 
 #define BUNfndVOID(b, v)                                               \
-       (((*(const oid*)(v) == oid_nil) ^ ((b)->tseqbase == oid_nil)) | \
+       ((is_oid_nil(*(const oid*)(v)) ^ is_oid_nil((b)->tseqbase)) |   \
                (*(const oid*)(v) < (b)->tseqbase) |                    \
                (*(const oid*)(v) >= (b)->tseqbase + (b)->batCount) ?   \
         BUN_NONE :                                                     \
         (BUN) (*(const oid*)(v) - (b)->tseqbase))
 
-#define BATttype(b)    ((b)->ttype == TYPE_void && (b)->tseqbase != oid_nil ? \
+#define BATttype(b)    ((b)->ttype == TYPE_void && !is_oid_nil((b)->tseqbase) 
? \
                         TYPE_oid : (b)->ttype)
 #define Tbase(b)       ((b)->tvheap->base)
 
@@ -1528,19 +1529,19 @@ gdk_export void GDKqsort(void *h, void *
 gdk_export void GDKqsort_rev(void *h, void *t, const void *base, size_t n, int 
hs, int ts, int tpe);
 
 #define BATtordered(b) ((b)->ttype == TYPE_void || (b)->tsorted)
-#define BATtrevordered(b) (((b)->ttype == TYPE_void && (b)->tseqbase == 
oid_nil) || (b)->trevsorted)
-#define BATtdense(b)   (BATtvoid(b) && (b)->tseqbase != oid_nil)
+#define BATtrevordered(b) (((b)->ttype == TYPE_void && 
is_oid_nil((b)->tseqbase)) || (b)->trevsorted)
+#define BATtdense(b)   (BATtvoid(b) && !is_oid_nil((b)->tseqbase))
 #define BATtvoid(b)    (((b)->tdense && (b)->tsorted) || (b)->ttype==TYPE_void)
 #define BATtkey(b)     (b->tkey != FALSE || BATtdense(b))
 
 /* set some properties that are trivial to deduce */
 #define BATsettrivprop(b)                                              \
        do {                                                            \
-               assert((b)->hseqbase != oid_nil);                       \
+               assert(!is_oid_nil((b)->hseqbase));                     \
                (b)->batDirtydesc = 1;  /* likely already set */        \
                /* the other head properties should already be correct */ \
                if ((b)->ttype == TYPE_void) {                          \
-                       if ((b)->tseqbase == oid_nil) {                 \
+                       if (is_oid_nil((b)->tseqbase)) {                \
                                (b)->tnonil = (b)->batCount == 0;       \
                                (b)->tnil = !(b)->tnonil;               \
                                (b)->trevsorted = 1;                    \
@@ -1570,7 +1571,7 @@ gdk_export void GDKqsort_rev(void *h, vo
                        } else if ((b)->ttype == TYPE_oid) {            \
                                /* b->batCount == 1 */                  \
                                oid sqbs;                               \
-                               if ((sqbs = ((oid *) (b)->theap.base)[0]) == 
oid_nil) { \
+                               if (is_oid_nil((sqbs = ((oid *) 
(b)->theap.base)[0]))) { \
                                        (b)->tdense = 0;                \
                                        (b)->tnonil = 0;                \
                                        (b)->tnil = 1;                  \
@@ -1791,7 +1792,7 @@ gdk_export BAT *BBPquickdesc(bat b, int 
  * value. `val' is a direct pointer to the atom value. Its return
  * value should be an hash_t between 0 and 'mask'.
  *
- * @item The @emph{ATOMcmp()} operation computes two atomic
+ * @item The @emph{ATOMcmp()} operation compares two atomic
  * values. Its parameters are pointers to atomic values.
  *
  * @item The @emph{ATOMlen()} operation computes the byte length for a
@@ -1892,7 +1893,6 @@ gdk_export int ATOMindex(const char *nme
 gdk_export str ATOMname(int id);
 gdk_export size_t ATOMlen(int id, const void *v);
 gdk_export ptr ATOMnil(int id);
-gdk_export int ATOMcmp(int id, const void *v_1, const void *v_2);
 gdk_export int ATOMprint(int id, const void *val, stream *fd);
 gdk_export char *ATOMformat(int id, const void *val);
 
@@ -2428,7 +2428,7 @@ gdk_export void *THRdata[THREADDATA];
 static inline bat
 BBPcheck(bat x, const char *y)
 {
-       if (x && x != bat_nil) {
+       if (!is_bat_nil(x)) {
                assert(x > 0);
 
                if (x < 0 || x >= getBBPsize() || BBP_logical(x) == NULL) {
@@ -2458,7 +2458,7 @@ static inline char *
 Tpos(BATiter *bi, BUN p)
 {
        bi->tvid = bi->b->tseqbase;
-       if (bi->tvid != oid_nil)
+       if (!is_oid_nil(bi->tvid))
                bi->tvid += p;
        return (char*)&bi->tvid;
 }
@@ -2769,7 +2769,7 @@ gdk_export void ALIGNsetT(BAT *b1, BAT *
        for (hb = HASHget(h, hash_##TYPE(h, v));                \
             hb != HASHnil(h);                                  \
             hb = HASHgetlink(h,hb))                            \
-               if (simple_EQ(v, BUNtloc(bi, hb), TYPE))
+               if (* (const TYPE *) v == * (const TYPE *) BUNtloc(bi, hb))
 
 #define HASHloop_bte(bi, h, hb, v)     HASHloop_TYPE(bi, h, hb, v, bte)
 #define HASHloop_sht(bi, h, hb, v)     HASHloop_TYPE(bi, h, hb, v, sht)
diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -10,7 +10,11 @@
 #include "gdk.h"
 #include "gdk_private.h"
 #include "gdk_calc_private.h"
+#if defined(_MSC_VER) && defined(__INTEL_COMPILER)
+#include <mathimf.h>
+#else
 #include <math.h>
+#endif
 
 /* grouped aggregates
  *
@@ -100,12 +104,12 @@ BATgroupaggrinit(BAT *b, BAT *g, BAT *e,
                                gids = (const oid *) Tloc(g, 0);
                                /* find first non-nil */
                                for (i = 0, ngrp = BATcount(g); i < ngrp; i++, 
gids++) {
-                                       if (*gids != oid_nil) {
+                                       if (!is_oid_nil(*gids)) {
                                                min = *gids;
                                                break;
                                        }
                                }
-                               if (min != oid_nil) {
+                               if (!is_oid_nil(min)) {
                                        /* found a non-nil, max must be last
                                         * value (and there is one!) */
                                        max = * (const oid *) Tloc(g, 
BUNlast(g) - 1);
@@ -114,7 +118,7 @@ BATgroupaggrinit(BAT *b, BAT *g, BAT *e,
                                /* we'll do a complete scan */
                                gids = (const oid *) Tloc(g, 0);
                                for (i = 0, ngrp = BATcount(g); i < ngrp; i++, 
gids++) {
-                                       if (*gids != oid_nil) {
+                                       if (!is_oid_nil(*gids)) {
                                                if (*gids < min)
                                                        min = *gids;
                                                if (*gids > max)
@@ -147,6 +151,318 @@ BATgroupaggrinit(BAT *b, BAT *g, BAT *e,
 /* ---------------------------------------------------------------------- */
 /* sum */
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to