Underscoring the underscore :)

The offical for ZeosLib 7.3 Report problems, ask for help, post proposals for the new version of Zeoslib 7.3/v8
Quick Info:
-We made two new drivers: odbc(raw and unicode version) and oledb
-GUID domain/field-defined support for FB
-extended error infos of Firebird
-performance ups are still in queue
In future some more feature will arrive, so stay tuned and don't hassitate to help
Post Reply
MJFShark
Expert Boarder
Expert Boarder
Posts: 211
Joined: 04.06.2020, 13:59

Underscoring the underscore :)

Post by MJFShark »

Hi All!

Since the various "gettables" , "getprocedures", "getcolumns" and such metadata calls allow passing in a pattern, and the ConstructNameCondition call is often used in creating the data dictionary queries, we run into an issue where any table with an underscore causes a "like" clause instead of an equals clause (which could lead to some incorrect results and possibly slower queries, though I suspect that would be rare.) There are some notes in the code about it in the FillWildCards method, that point to viewtopic.php?f=40&t=13184 and I think we should implement the suggested change (or some other way if it's a problem) and document that only '%' wildcards are allowed in the metadata tablepattern-like arguments.

-Mark
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1918
Joined: 17.01.2011, 14:17

Re: Underscoring the underscore :)

Post by marsupilami »

Hello Mark,

I am not sure how this popped up for you. Normally the user is expected to escape wildcards if they are part of the object name. Meaning that if you want to use GetColumns and you want to search for 'TABLE_NAME' then you should call it with something like this:

Code: Select all

GetColumns('%', '%', 'TABLE\_NAME', '%').
This assumes that the '\' character is the default escape character for wildcard searches. If you need to generalize this, the use of IZDatabaseMetadata.AddEscapeCharToWildcards is suggested. IZDatabaseInfo.GetSearchStringEscape should return the default escape character for the database in use. Usually ConstructNameCondition can detect these cases (by using HasNoWildcards) and remove the wildcards (by using StripEscape) to form a regular comparision using the '=' operator.

So - usually it is not necessary to disable wildcards. If using escape characters doesn't solve the problem, this might be a bug in Zeos.

On the driver side things can get tricky too. MS SQL Server (and probably others) don't have a default escape character. On these systems one has to add an escape clause in searches. TZMsSqlDatabaseMetadata.UncachedGetColumns does that in the second part. Queries could look like this:

Code: Select all

select ... from COLUMNSTABLE T where T.COLUMNNAME like 'TABLE\_NAME' escape '\';
Best regards,

Jan
MJFShark
Expert Boarder
Expert Boarder
Posts: 211
Joined: 04.06.2020, 13:59

Re: Underscoring the underscore :)

Post by MJFShark »

Hi Jan,

On looking further I see that "internal" metadata calls use AddEscapeCharToWildcards on those arguments, I wasn't aware of that and so was having the issue only in my own testing. I'll look into doing something similar for my "external" metadata calls that don't need wildcards. Thanks for the clarification!

-Mark
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1918
Joined: 17.01.2011, 14:17

Re: Underscoring the underscore :)

Post by marsupilami »

Erm - you could use AddEscapeCharToWildcards too? This is a service function. It should be available from the Component layer as TZConnection.DbcConnection.GetMetadata.AddEscapeCharToWildcards().
MJFShark
Expert Boarder
Expert Boarder
Posts: 211
Joined: 04.06.2020, 13:59

Re: Underscoring the underscore :)

Post by MJFShark »

Ha! Yes, "something similar" may just be calling that function!

-Mark
MJFShark
Expert Boarder
Expert Boarder
Posts: 211
Joined: 04.06.2020, 13:59

Re: Underscoring the underscore :)

Post by MJFShark »

It looks like there's no workaround for Oracle (and I assume SQLServer?) I suppose it's not that big of an issue, it would be pretty rare to have multiple tables that would match just based on a single underscore wildcard. I guess it is what it is.

-Mark
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1918
Joined: 17.01.2011, 14:17

Re: Underscoring the underscore :)

Post by marsupilami »

According to https://docs.oracle.com/cd/B13789_01/server.101/b10759/conditions016.htm Oracle also doesn't have a default escape character:
If esc_char is not specified, then there is no default escape character.
So, to be able to correctly search we have to modify the oracle driver to use an escape character and specify it when querying for data. On MS SQL Server we use system stored procedures for most of the data. UncachedGetColumns already specifies an escape character when looking up additional data on fields. I don't remember how SQL Server workw with wildcard characters and escaping in the stored procedures. I can only assume that they use '\' automatically there...
User avatar
EgonHugeist
Zeos Project Manager
Zeos Project Manager
Posts: 1936
Joined: 31.03.2011, 22:38

Re: Underscoring the underscore :)

Post by EgonHugeist »

Don't make it so complicated. It's just dblib which uses this syntax. Use StripEscape instead and test with HasNoWildCards if a like or equal search needs to be made...
Best regards, Michael

You want to help? http://zeoslib.sourceforge.net/viewtopic.php?f=4&t=3671
You found a (possible) bug? Use the new bugtracker dude! http://sourceforge.net/p/zeoslib/tickets/

Image
MJFShark
Expert Boarder
Expert Boarder
Posts: 211
Joined: 04.06.2020, 13:59

Re: Underscoring the underscore :)

Post by MJFShark »

It's certainly an interesting issue (and yes you're correct about Oracle.) Really the metadata 'get' functions all serve double duty. They're either 'get' or 'search' depending on if wildcards are there. It's just that detecting the wildcards is iffy due to SQL's underscore issues lol. I suppose the only real solution (if it needs to handle '_' wildcards that is) is to include a UseWildcards parameter that defaults to true (for backwards compatibility.) But, that's just one possible solution off the top of my head, I'm not sure it's worth it.

By the way, looking through some of this code it seems odd that the Oracle metadata's escape string is set to '\\', and that the default in metadata is '%'.

-Mark
Also, I hope that my comments here aren't seen as negative... this is an amazing library!
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1918
Joined: 17.01.2011, 14:17

Re: Underscoring the underscore :)

Post by marsupilami »

EgonHugeist wrote: 11.12.2020, 23:16 Don't make it so complicated. It's just dblib which uses this syntax. Use StripEscape instead and test with HasNoWildCards if a like or equal search needs to be made...
Asuming the following:
You have six tables: TABLE_NAME_A, TABLE_NAME_B, TABLE_NAME_AA, TABLE_NAME_BB, TABLExNAME_A, TABLExNAME_B. You want to get metadata for TABLE_NAME_A and TABLE_NAME_B only in one go. So your pattern could look something like this:
'TABLE\_NAME\__'
The second underscore is there to make sure, that you only get tables with A and B and not AA or BB...

How is that going to work without using
... like 'TABLE\_NAME\__' escape '\'
on Oracle?
MJFShark
Expert Boarder
Expert Boarder
Posts: 211
Joined: 04.06.2020, 13:59

Re: Underscoring the underscore :)

Post by MJFShark »

It's also odd that the Oracle SupportsNonEscapedSearchString has a client version check. I don't think it ever supported an escape string without the escape '\' clause, regardless of the server or client version.

-Mark
User avatar
EgonHugeist
Zeos Project Manager
Zeos Project Manager
Posts: 1936
Joined: 31.03.2011, 22:38

Re: Underscoring the underscore :)

Post by EgonHugeist »

@Jan
seems correct. I just thought about SQL Server: https://docs.microsoft.com/en-us/sql/t- ... rver-ver15 Escape:

Code: Select all

[_] or [%]
this syntax is known on any Sybase too. But if a server does'nt support it.. We need the escape syntax, of course.
Best regards, Michael

You want to help? http://zeoslib.sourceforge.net/viewtopic.php?f=4&t=3671
You found a (possible) bug? Use the new bugtracker dude! http://sourceforge.net/p/zeoslib/tickets/

Image
Post Reply