bmuller / twistar

Twistar is an object-relational mapper (ORM) for Python that uses the Twisted library to provide asynchronous DB interaction.

Home Page:http://findingscience.com/twistar

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

validatesUniquenessOf triggers Segmentation Fault in a particular case

Reve opened this issue · comments

The seg fault is triggered when you try to validate the uniqueness of a random string ("xn--tan-test-20160307154100-6tc060eub.ro"). validatePresenceOf works well with the same string provided. By looking at the stack trace, I think the problem is related to the Inflector but I am not 100% sure.

I will attach the stack trace below:

Thank you

`(gdb) bt
#0 call_function (f=, throwflag=) at Python/ceval.c:3796
#1 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#2 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x1d18288, globals=, locals=, args=, argcount=1,

kws=0x1ddfdf0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#3 0x0000003cda26ad9d in function_call (func=<function at remote 0x1d25848>, arg=

(<Domain(_config=<PostgreSQLDBConfig(txn=None) at remote 0x1d78ea8>, errors=<Errors(infl=<Inflector(Inflector=<English() at remote 0x1d6ff38>) at remote 0x1d6ffc8>) at remote 0x1ddfce0>, user_id=277, fqdn='xn--tan-test-20160307154100-6tc060eub.ro', _deleted=False, id=None) at remote 0x1d70b50>,), kw={})
at Objects/funcobject.c:524

#4 0x0000003cda243c63 in PyObject_Call (func=<function at remote 0x1d25848>, arg=, kw=) at Objects/abstract.c:2492
#5 0x0000003cda2d4460 in ext_do_call (f=, throwflag=) at Python/ceval.c:4107
#6 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2493
#7 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7378, globals=, locals=, args=,

argcount=1, kws=0x1e09cc8, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#8 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#9 call_function (f=, throwflag=) at Python/ceval.c:3815
#10 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#11 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x1d0d288, globals=, locals=, args=, argcount=1,

kws=0x1e09ae0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#12 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#13 call_function (f=, throwflag=) at Python/ceval.c:3815
#14 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#15 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x1d05c60, globals=, locals=, args=, argcount=1,

kws=0x17e4740, kwcount=0, defs=0x0, defcount=0, closure=(<cell at remote 0x1d7b4e8>,)) at Python/ceval.c:3044

#16 0x0000003cda26ad9d in function_call (func=<function at remote 0x1d73320>, arg=(True,), kw={}) at Objects/funcobject.c:524
#17 0x0000003cda243c63 in PyObject_Call (func=<function at remote 0x1d73320>, arg=, kw=) at Objects/abstract.c:2492
#18 0x0000003cda2d4460 in ext_do_call (f=, throwflag=) at Python/ceval.c:4107
#19 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2493
#20 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7d50, globals=, locals=, args=,

argcount=1, kws=0x1e08ab8, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#21 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#22 call_function (f=, throwflag=) at Python/ceval.c:3815
#23 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#24 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7c60, globals=, locals=, args=,

argcount=2, kws=0x1e088e8, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#25 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#26 call_function (f=, throwflag=) at Python/ceval.c:3815
#27 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#28 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7918, globals=, locals=, args=,

argcount=2, kws=0x1e08708, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#29 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#30 call_function (f=, throwflag=) at Python/ceval.c:3815
#31 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#32 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f02583f0, globals=, locals=, args=,

argcount=4, kws=0x11d9880, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#33 0x0000003cda26ad9d in function_call (func=<function at remote 0x7f01f0263410>, arg=

(<DeferredList(finishedCount=2, _chainedTo=None, fireOnOneCallback=False, resultList=[(True, None), (True, None)], _runningCallbacks=True, _canceller=None, callbacks=[((<function at remote 0x1d6ced8>, (), {}), (<function at remote 0x1d6ced8>, (...), {...}))], fireOnOneErrback=False, result=True, _deferredList=[<Deferred(_chainedTo=None, called=True, _canceller=None, callbacks=[], result=None, _runningCallbacks=False) at remote 0x1d6fef0>, <DeferredList(finishedCount=1, _chainedTo=None, fireOnOneCallback=False, resultList=[(True, None)], _runningCallbacks=True, _canceller=None, callbacks=[], fireOnOneErrback=False, result=None, _deferredList=[<Deferred(_chainedTo=None, called=True, _canceller=None, callbacks=[], result=None, _runningCallbacks=True) at remote 0x1d6fea8>], called=True, consumeErrors=False) at remote 0x1d780e0>], called=True, consumeErrors=False) at remote 0x1d78e60>, None, 1, True), kw={}) at Objects/funcobject.c:524

#34 0x0000003cda243c63 in PyObject_Call (func=<function at remote 0x7f01f0263410>, arg=, kw=) at Objects/abstract.c:2492

---Type to continue, or q to quit---
#35 0x0000003cda2d4460 in ext_do_call (f=, throwflag=) at Python/ceval.c:4107
#36 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2493
#37 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7d50, globals=, locals=, args=,

argcount=1, kws=0x1dcf7b8, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#38 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#39 call_function (f=, throwflag=) at Python/ceval.c:3815
#40 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#41 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7c60, globals=, locals=, args=,

argcount=2, kws=0x1e076b8, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#42 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#43 call_function (f=, throwflag=) at Python/ceval.c:3815
#44 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#45 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7918, globals=, locals=, args=,

argcount=2, kws=0x1de5008, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#46 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#47 call_function (f=, throwflag=) at Python/ceval.c:3815
#48 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#49 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f02583f0, globals=, locals=, args=,

argcount=4, kws=0x1d4d8b0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#50 0x0000003cda26ad9d in function_call (func=<function at remote 0x7f01f0263410>, arg=

(<DeferredList(finishedCount=1, _chainedTo=None, fireOnOneCallback=False, resultList=[(True, None)], _runningCallbacks=True, _canceller=None, callbacks=[], fireOnOneErrback=False, result=None, _deferredList=[<Deferred(_chainedTo=None, called=True, _canceller=None, callbacks=[], result=None, _runningCallbacks=True) at remote 0x1d6fea8>], called=True, consumeErrors=False) at remote 0x1d780e0>, None, 0, True), kw={}) at Objects/funcobject.c:524

#51 0x0000003cda243c63 in PyObject_Call (func=<function at remote 0x7f01f0263410>, arg=, kw=) at Objects/abstract.c:2492
#52 0x0000003cda2d4460 in ext_do_call (f=, throwflag=) at Python/ceval.c:4107
#53 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2493
#54 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7d50, globals=, locals=, args=,

argcount=1, kws=0x1de4bc8, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#55 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#56 call_function (f=, throwflag=) at Python/ceval.c:3815
#57 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#58 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7c60, globals=, locals=, args=,

argcount=2, kws=0x1de44b8, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#59 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#60 call_function (f=, throwflag=) at Python/ceval.c:3815
#61 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#62 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f06e7918, globals=, locals=, args=,

argcount=2, kws=0x1dbab50, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#63 0x0000003cda26ad9d in function_call (func=<function at remote 0x7f01f0264c08>, arg=

(<Deferred(_chainedTo=None, called=True, _canceller=None, callbacks=[], result=None, _runningCallbacks=True) at remote 0x1d6fea8>, None), kw={})
at Objects/funcobject.c:524

#64 0x0000003cda243c63 in PyObject_Call (func=<function at remote 0x7f01f0264c08>, arg=, kw=) at Objects/abstract.c:2492
#65 0x0000003cda2d4460 in ext_do_call (f=, throwflag=) at Python/ceval.c:4107
#66 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2493
#67 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x16db7b0, globals=, locals=, args=, argcount=1,

kws=0x1dcf4a8, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#68 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#69 call_function (f=, throwflag=) at Python/ceval.c:3815
#70 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#71 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x16e0a80, globals=, locals=, args=, argcount=1,

kws=0x1dcde80, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#72 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890

---Type to continue, or q to quit---
#73 call_function (f=, throwflag=) at Python/ceval.c:3815
#74 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#75 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x16e0990, globals=, locals=, args=, argcount=1,

kws=0x1dcdc90, kwcount=0, defs=0x16f7728, defcount=1, closure=0x0) at Python/ceval.c:3044

#76 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#77 call_function (f=, throwflag=) at Python/ceval.c:3815
#78 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#79 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f273fcd8, globals=, locals=, args=,

argcount=5, kws=0x1dcdaa8, kwcount=0, defs=0x7f01f06ce188, defcount=2, closure=0x0) at Python/ceval.c:3044

#80 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#81 call_function (f=, throwflag=) at Python/ceval.c:3815
#82 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#83 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f2745030, globals=, locals=, args=,

argcount=4, kws=0x1dbe958, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#84 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#85 call_function (f=, throwflag=) at Python/ceval.c:3815
#86 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#87 0x0000003cda2d6b7f in fast_function (f=, throwflag=) at Python/ceval.c:3880
#88 call_function (f=, throwflag=) at Python/ceval.c:3815
#89 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#90 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f273ff30, globals=, locals=, args=,

argcount=1, kws=0x140f258, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#91 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#92 call_function (f=, throwflag=) at Python/ceval.c:3815
#93 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#94 0x0000003cda2d6b7f in fast_function (f=, throwflag=) at Python/ceval.c:3880
#95 call_function (f=, throwflag=) at Python/ceval.c:3815
#96 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#97 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f2745a08, globals=, locals=, args=,

argcount=2, kws=0x1416a60, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#98 0x0000003cda2d5a94 in fast_function (f=, throwflag=) at Python/ceval.c:3890
#99 call_function (f=, throwflag=) at Python/ceval.c:3815
#100 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#101 0x0000003cda2d6b7f in fast_function (f=, throwflag=) at Python/ceval.c:3880
#102 call_function (f=, throwflag=) at Python/ceval.c:3815
#103 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2453
#104 0x0000003cda2d7647 in PyEval_EvalCodeEx (co=0x7f01f3e8a558, globals=, locals=, args=,

argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3044

#105 0x0000003cda2d7722 in PyEval_EvalCode (co=, globals=, locals=) at Python/ceval.c:545
#106 0x0000003cda2f1b9c in run_mod (mod=, filename=, globals=

{'run': <function at remote 0x7f01f2745230>, '__builtins__': <module at remote 0x7f01f3f3c868>, '__file__': '/usr/bin/twistd', '__package__': None, 'sys': <module at remote 0x7f01f3f3cc20>, '__name__': '__main__', 'os': <module at remote 0x7f01f3eef9b8>, '__doc__': None}, locals=
{'run': <function at remote 0x7f01f2745230>, '__builtins__': <module at remote 0x7f01f3f3c868>, '__file__': '/usr/bin/twistd', '__package__': None, 'sys': <module at remote 0x7f01f3f3cc20>, '__name__': '__main__', 'os': <module at remote 0x7f01f3eef9b8>, '__doc__': None}, flags=<value optimized out>,
arena=<value optimized out>) at Python/pythonrun.c:1358

#107 0x0000003cda2f1c70 in PyRun_FileExFlags (fp=0x1097630, filename=0x7ffd72c495f3 "/usr/bin/twistd", start=, globals=

{'run': <function at remote 0x7f01f2745230>, '__builtins__': <module at remote 0x7f01f3f3c868>, '__file__': '/usr/bin/twistd', '__package__': None, 'sys': <module at remote 0x7f01f3f3cc20>, '__name__': '__main__', 'os': <module at remote 0x7f01f3eef9b8>, '__doc__': None}, locals=
{'run': <function at remote 0x7f01f2745230>, '__builtins__': <module at remote 0x7f01f3f3c868>, '__file__': '/usr/bin/twistd', '__package__': None, 'sys': <module at remote 0x7f01f3f3cc20>, '__name__': '__main__', 'os': <module at remote 0x7f01f3eef9b8>, '__doc__': None}, closeit=1, flags=0x7ffd72c48520)
at Python/pythonrun.c:1344

#108 0x0000003cda2f315c in PyRun_SimpleFileExFlags (fp=0x1097630, filename=0x7ffd72c495f3 "/usr/bin/twistd", closeit=1, flags=0x7ffd72c48520)

---Type to continue, or q to quit---
at Python/pythonrun.c:948
#109 0x0000003cda2ff892 in Py_Main (argc=, argv=) at Modules/main.c:618
#110 0x00000039cd21ed5d in __libc_start_main (main=0x400710

, argc=6, ubp_av=0x7ffd72c48648, init=, fini=,

rtld_fini=<value optimized out>, stack_end=0x7ffd72c48638) at libc-start.c:226

#111 0x0000000000400649 in _start ()`

Thanks @Reve - do you have an example script that will demonstrate this?

from twistar.dbobject import DBObject

class Domain(DBObject):
    TABLENAME = 'domain'
    HABTM = ['tags']

    searchable_fields = ['id', 'user_id', 'fqdn', 'crdate']
    sortable_fields = ['user_id', 'fqdn', 'crdate']

    id = None
    user_id = None
    fqdn = None
    crdate = None

Domain.validatesPresenceOf('user_id', 'fqdn')
# This here throws segmentation fault
Domain.validatesUniquenessOf('fqdn')

And this is called in a command. The script dies on save().

db_domain = Domain()
db_domain.user_id = _user_id
db_domain.fqdn = domain
dom = yield db_domain.save()

Thanks @Reve - can you post a full proof of issue (all the code necessary to duplicate)? It could just use SQLite locally and some initial command to create a table.

I will try to see if I can isolate the issue and post a followup here.

Now it's working after a few twisted restarts. I am not sure what caused it... Thank you very much for your time.

No worries! Let me know if you run into any other issues.

I think I finally isolated the issue. The error occurs if it's the first thing you invoke after the twisted server start. If I do a select from the DB before the save, it works. This is very strange and since it's deferred it's very hard to debug.

I did find a solution to the problem by adding the code below before the save() function is called.

validation_result = yield db_domain.isValid()
if validation_result is False:
                raise CommandParameterInvalidError(str(db_domain.errors), '50000')`

If this is the way you should validate things, I suggest that you add it to the documentation so future users will avoid this problem.

Thank you again

Thanks for debugging @Reve - I'll take a look.

I found where the problem was. I was formating the Timestamp using the native Timestamp obtained by calling Registry.getDBAPIClass("Timestamp") and for some unknown reason it would throw a segmentation fault saying that it could not find Timestamp class/library.

Strace output:

epoll_wait(8, {{EPOLLIN, {u32=9, u64=15719776338552291337}}}, 4, 221) = 1
read(9, "xx", 8192)                     = 2
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2195, ...}) = 0
write(1, "2016-03-23 15:52:04+0200 [-] TWI"..., 80) = 80
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2195, ...}) = 0
write(3, "2016-03-23 15:52:04+0200 [-] TWI"..., 80) = 80
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2195, ...}) = 0
write(1, "2016-03-23 15:52:04+0200 [-] TWI"..., 65) = 65
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2195, ...}) = 0
write(3, "2016-03-23 15:52:04+0200 [-] TWI"..., 65) = 65
rt_sigprocmask(SIG_BLOCK, [PIPE], [], 8) = 0
sendto(14, "Q\0\0\0:BEGIN; SET TRANSACTION ISOL"..., 59, 0, NULL, 0) = 59
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
poll([{fd=14, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=14, revents=POLLIN}])
recvfrom(14, "C\0\0\0\nBEGIN\0C\0\0\0\10SET\0Z\0\0\0\5T", 16384, 0, NULL, NULL) = 26
rt_sigprocmask(SIG_BLOCK, [PIPE], [], 8) = 0
sendto(14, "Q\0\0\0>SELECT * FROM tags WHERE (t"..., 63, 0, NULL, 0) = 63
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
poll([{fd=14, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=14, revents=POLLIN}])
recvfrom(14, "T\0\0\0001\0\2id\0\0\1\26\345\0\1\0\0\0\27\0\4\377\377\377\377\0\0tag\0"..., 16384, 0, NULL, NULL) = 68
stat("/usr/lib64/python2.6/site-packages/psycopg2/Timestamp", 0x7ffc43fbd470) = -1 ENOENT (No such file or directory)
open("/usr/lib64/python2.6/site-packages/psycopg2/Timestamp.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib64/python2.6/site-packages/psycopg2/Timestampmodule.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib64/python2.6/site-packages/psycopg2/Timestamp.py", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib64/python2.6/site-packages/psycopg2/Timestamp.pyc", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2195, ...}) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
Process 12418 detached

I was using psycopg2 version 2.0.14. I've updated to the latest 2.6.1 and the problem disappeared. I think it should be noted somewhere which should be the minimum requirements for the dependencies.

Thank you very much once again.