This thing is driving me nuts and I'm hoping someone will see a glimmer of
sense in it.
Let me start off by saying that I did post about this a while back and got
an (as usual) informative response from Ted regarding causes of Error 2115
("Execution of function or command is not allowed in context of SQL
command.") Ted suggested that something in a macro-expanded query
expression was being misinterpreted as a UDF.
So I added the ability to save the last-executed query expression to my
error log file, and this gave me some more information. However, it
disproves the UDF theory. And the history of the error is completely screwy.
Using VFP 9 SP1. Executable application runs on local workstations using
Win XP Pro or Windows 7 Ultimate (both 32-bit), and accesses shared VFP
tables on a CentOS Linux server using SAMBA.
This error occurs infrequently; in other words, most of the time the code
I'm about to describe works just fine. To anticipate one possible
suggestion, the error occurred again this morning using a completely
recompiled version of the program.
When it occurs, it occurs while someone is shutting down my application. In
this particular case, this was an orderly shutdown, started by pressing the
"X" button in the upper right corner of the application's main window.
There is a bunch of things that happen during the course of the shutdown.
I've talked about that before here, and for now let's just assume that they
are all excellent ideas and should work out fine.
The application uses both some local lookup tables on the individual
workstation, and many shared-access tables on a server. One of the tasks
during shutdown is to PACK the local tables. Another task is to make an
audit log entry in a shared table showing that the user logged out at such
and such a time. This requires creating a new record, which in my framework
is done via APPEND BLANK. The PK field of the table has a default value
expression which calls a UDF called GetKey(). Oh, and I always include
debugging information in my builds, so the error logs will be as complete
as possible.
I think that's probably enough background.
So when Error 2115 occurs my error log reports the following:
LINENO(1), which is supposed to return the line of the CURRENT procedure or
program that generated the error, says the offending line is Line 23.
Since PROGRAM() can return unreliable results, my code always keeps track
of the currently-executing object.procedure name and passes that to the
error handler instead. In this case, the currently-executing procedure was:
MaintenanceMgr.PackTables().
If we count comments and blank lines, Line 23 of PackTables() is an
initilization of a local variable:
errcloser = ""
If we only count code lines, then Line 23 of PackTables() is another string
variable assignment:
scanfor = "NOT DELETED() AND NOT EMPTY(dicttable)"
Dicttable is the name of a character field in the table about to be
scanned. Aside from opinions about use of DELETED(), I don't see anything
wrong with either of those lines.
But it gets stranger.
Because also at this time, MESSAGE(1), which is supposed to return the line
of code that caused the error, says that the offending code is:
GetKey(oApp.pTablename)
That is the contents of the default value expression for all of the tables
in my application.
But remember, this is supposed to be Error 2115, a problem in the context
of a SQL expression, right?
So my error log records the most recently-executed query as:
SELECT configx.modname, configx.modcode FROM "F:\cildata2\configx" INTO
CURSOR tmpAvailMods NOFILTER
I first thought that using a table name without a .dbf extension in a path
expression might cause a problem, but this query works fine in the command
window.
It is of course possible that F: (a mapped drive on the server) and its
contents are unavailable, but that shouldn't trigger Error 2115. It should
typically trigger Error 1 ("File does not exist")--and I've seen that happen.
When this error occurs, the value of oApp.pTablename is "tryware", which is
the audit-trail table. If GetKey() was actually called, then it would have
been by my Data Manager base class's NewRecord() method, which would be
called by a chain of methods beginning in the business object for the
tryware table.
My error log contains info from ASTACKINFO() so I get a complete trace. The
routine that records the audit-trail record does not appear in the trace.
None of that chain of methods was called.
So, to summarize:
At the time when Error 2115 occurs, my application is apparently assigning
a string value to a variable in a method of a non-visual object, but it is
also apparently simultaneously trying to create a new record in the
audit-trail table using APPEND BLANK--even though the stack trace shows
nothing that could have done that. Neither of these things is part of an
executing SQL query expression which, in any case, is error-free at
design-time.
And by the way, I get a lot of error logs that claim the executing line of
code is that PK default value expression, in various contexts, and
LINENO(1) will always say it's line 23. Just for grins, in the GetKey()
function, if we count comments and blank lines, line 23 is a comment. If we
only count code lines, line 23 is the second line of a semi-colon-broken
two-line assignment of a string value to a local variable.
Obviously, at least some of what these VFP functions are reporting to me is
hogwash. The only thing I can think of is, this is a routine that PACKs
tables, even though it is demonstrably (according to the trace) only
PACKing local tables, not those on the server, and even though, according
to the other error data, the line that actually says PACK is not being
called. I would think and hope that PACK doesn't trigger a table's
default-value expression.
Are we having fun yet?
Can anybody find the light at the end of this tunnel?
Thanks.
Ken Dibble
www.stic-cil.org
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://mail.leafe.com/mailman/listinfo/profox
OT-free version of this list: http://mail.leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message:
http://leafe.com/archives/byMID/profox/[email protected]
** All postings, unless explicitly stated otherwise, are the opinions of the
author, and do not constitute legal or medical advice. This statement is added
to the messages for those lawyers who are too stupid to see the obvious.