Subject Re: [IBO] TIBOQuery generating invalid SQL "under the hood"
Author Bjørge Sæther
"Helen Borrie" <helebor@...> skrev i melding
news:5.1.0.14.2.20030213114356.062ace98@......
> At 01:11 AM 13/02/2003 +0100, you wrote:

Sorry for the delay, my Outlook Express started crashing. I have attempted
answered this posting 3 times, but OE crashed before I finished.

> >My SQL was like this:
> >
> >SELECT
> > *
> >FROM
> > INVOICE
> >
> >...and the trouble:
> >
> >Table INVOICE doesn't exist.
> >Or - it doesn't have a PRIMARY KEY.
>
> Well, these are two different problems.

I know. But the error message has nothing to do with the underlying errors.

> >Both of these cases results in an added field
> > ", INVOICE.RDB$DBKEY"
> >..which is rather pointless for more reasons:
> >
> >a) The select statement is no longer valid SQL syntax
>
> What you got was the IBO parser's attempt to make sense out of bad
> SQL. The parser itself doesn't know it is bad SQL until the DSQL parser
on
> the server throws an error at prepare time.

You actually mean "select * form tablex" is *bad* sql ? Come on !

> >b) Why on earth add this info when I only want to make a select call ?
>
> Because IBO needs to have a unique "handle" on each row, for use when
> swapping rows in and out of the buffers. Because you didn't supply it
(via
> KeyLinks) and asked IBO to try (KeyLinksAutoDefine True) then IBO tried to
> do it. It failed because of another error in the statement.

There was no error in the original statement.

> >c) Why couldn't the real reason be detected - that valid row identifier
> >field(s) cannot be added ?
>
> They can, provided the original SQL statement was valid. Your particular
> combination of SQL errors caused a rubbish statement to be generated, but
> the appending of the rdb$db_key itself is valid.

I just can't believe you actually mean this - an SQL parser that get the
hiccups from SELECT * FROM XXX is not a problem ?

> Take it from me, AVOID select *. It is there to comply with standards but
> it is not at all appropriate for use with an interface that implements
> behaviour that has the client buffers interacting with the cached output
> set on the server. If this conflicts with your requirements, you probably
> need to use ODBC, not IBO.

Within an application, I would hardly use SELECT * FROM XXX syntax. But SQL
is used for more things. There are cases - when you don't actually know the
structure at compile time, or when doing manual selects for some reason. If
a SELECT * .. can't be used, this means I have to write a parsing algorithm
to change it to SELECT XXX.* FROM XXX.
Having looked into statement preparation in IBO, I find this strange. There
is a *lot* of SQL parsing here. Why not detect the simple "*" ???

> >d) After error message is issued, there is, AFAIK, no way to read the
> >failing SQL call from the TIBOQuery. Too bad, as you do now have a
detailed
> >spec on where error occurred, but unfortunartely - not the original SQL
stmt
> >itself.
>
> If you are watching the API with a TIB_Monitor then you will see
everything
> that goes through the API. If it isn't what you expect then it's a sure
> sign that the sum of your application's requests is different to what you
> intended.

I allready found one bug - a TIBOQuery requesting for default values in a
readonly select. In this case I had an extra delay of some 2 seconds -
making IBO useless until the bug was located.
A person automatically assuming she or he is wrong when a component doesn't
work as expected wouldn't last long as a programmer. The good thing about
having a component's source code is ease of debugging. I'd not reflect on
using DB access components without source code.
TIB_Monitor is fine, but it doesn't explain why IBO modifies valid SQL
syntax to generate "invalid token ','" errors.

> >And now, the final quesions:
> >- Why isn't the source built up by .pas files ? The include files result
in
> >loss of syntax highlighting, makes searches hard, separates declarations
> >from source body.
>
> The IBO packages are built with a lot of conditional defines, so that the
> same sources work, regardless of Delphi version and edition. When
tracking
> through sources, just press Ctl-ENTER to jump to any unit ref'd in a USES
> clause.

Well, the cost is pretty high when you compare advantages to a few
developers to the inconvenience of thiousands of developers using the
components.

> >- Why is portions of code loaded with HTML within comments ???
>
> Because we use Time2Help to generate our helpfile. It lets you use
javadoc
> and html tags to customise the help text output. The INT files contain
the
> interface section of the corresponding PAS units. We put the help text in
> the INT comments so that it is all in the right place for maintaining and
> so that it can propagate to the descendant classes.

When you see the result, help entries like this:


property SomeProp: TSomeType;

...and nothing more, I'd like to ask what's the purpose ?

> >I must say, this day I have started thinking about whether the "IB move"
was
> >so smart after all. Loads of nice features make the components fragile.
>
> Fair comment, IBO needs a lot of skill with the OO features of Delphi and
a
> good understanding of SQL. We did the GSG to address the steep initial
> learning curve but, even with the GSG, you need a fairly high base level
of
> Delphi and DB skills. If you are new to client/server and haven't
> previously needed to get in touch with Delphi's object model, then it's
> quite true that the curve will be steeper.

Interesting "twist". The overall reason for my problems being I am an
unskilled programmer.

> This isn't a put-down - it's a personal observation of my own
> experience. I had the same frustrations as you to begin with and rejected
> IBO for a very important project in 1997 because I simply didn't know
> Delphi well enough. Three years later, I had to make myself do it,
because
> Jason asked me to write the GSG. The original version of that guide was
> the very direct result of that effort - me starting with IBO literally
from
> Ground Zero.

Having used Delphi for C/S applications since 1995, I have hesitated to
throw out BDE. Reason: BDE works, although it is far from perfect. There is
allways a slight anxiety involved when choosing a component set: "What if I
discover serious problems too late ?". And I don't mean "after I paid", but
rather "when there is no easy way back".

I Did throw out BDE once in 2000 in favour of Direct Oracle Access, and
instantly ran into trouble because of silly bugs. A few months later these
problems were sorted out, and DOA became my choice for Oracle.
Having worked with Delphi on IB since 1999, I have argued that my customer
should switch to native IB access. But I must say Delphi's IB support (via
BDE) has been quite solid, yet primitive. Choosing Firebird for the
application made a conversion even more desireable, and I finally had a
"go". Converting two applications in about one week with only one bugfix
wasn't that bad a result, but my anxiety was not removed: There are
certainly problems to be solved.

> >I've also been bothered with seemingly random accessviolations upon
startup,
> >especially after a crash. Some of these crashes are just overseen with a
> >brutal exception handler, so it won't bother a user. But it bothers me.
>
> I'd want to investigate why you get crashes and I would treat the AVs
> afterwards as a symptom of what caused the crash.

They are more or less random, and it seems like it has to do with memory
management. Debugger usually stops in some string- or memory allocation /
disposal.
They feed my anxiety.

> >Of course - a component vendor's coding style is normally no business of
> >mine. But in this case I *need* sources to be able to determine source of
> >problems, and features that are not documented. I find it almost
unreadable.
>
> There are some FAQ items regarding the structure of the sources, which
> might help. Also, get familiar with the IDE tools for exploring linked
> source files.

I am quite familiar with Delphi IDE. That's why am not happy about the way
IBO source files are organized.
Also, this kind of coding style shouldn't appear:

procedure TMyClass.DoSomething;
begin MyDelegatedObject.DoSomething; end;

...and don't even try to argue that this is preferred coding style !

regards,

Bj�rge S�ther