Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL Pattern Macros #19

Open
ondrej-bouda opened this issue Dec 7, 2017 · 2 comments
Open

SQL Pattern Macros #19

ondrej-bouda opened this issue Dec 7, 2017 · 2 comments

Comments

@ondrej-bouda
Copy link
Owner

ondrej-bouda commented Dec 7, 2017

It is easy to define custom data types and serializers. What might lead to even more flexible tool are SQL pattern macros.

Let us consider a simple task: we want to implement a serializer to IN (...) where the type of values is inferred and serialized automatically by Ivory using the same mechanism as for auto-typed SQL placeholders (i.e., those not specifying the type, such as a mere %). Today, this is not possible, just a serializer with a fixed type of values may be implemented.

The task is to extend the type registers and type dictionaries with macros, or, alternatively, extend value serializers. Essentially, the only thing which would allow macros might be passing the type dictionary along with the serialized value.

Also, consider reuse of simple serializers (or even data types) in more complex ones. E.g., if IValueSerializer::serializeValue() was also given the type dictionary or anything able to interpret SQL patterns, implementing geometric types such as LineSegmentType or CircleType would allow for easier reuse of the PointType. Even better, the %point could be serialized using the possibly overridden serializer, not strictly the one shipped with Ivory. May be, this could also be applicable to arrays and other complex types, too.

Still, do not extend the system with the possibility to pass multiple arguments to a single placeholder. Such flexibility could cause more harm than benefit. If something needs multiple values, just pass an array.

@jkuchar
Copy link

jkuchar commented Dec 13, 2017

Hmm. what is the use case? When do I need to do this?

@ondrej-bouda
Copy link
Owner Author

The original trigger for this issue was the impossibility to implement a generic IN(...) serializer, auto-detecting the types of list values (e.g., generating ('a', 'b', 'c') from a given list of strings while making (1, 2, 3) from a list of integers). If you want to serialize a list into this construct (and not to use arrays), the only way is to define one serializer for each type of list items.

When I encountered this, I also had the idea using the proposed feature to allow a serializer/type converter to reuse other serializers/type converters. For example, a LineSegmentType serializes to SQL a LineSegment object, which, however, consists of two Points. Those two points are serialized exactly the same as is a single point. The current approach to prevent code duplication is that LineSegmentType constructs a helper PointType object to serialize the points. It seems cleaner if a kind of macro "lseg(%point,%point)" was output instead by LineSegmentType alone, which could be passed for further processing - serializing the points themselves.
(A fact is that LineSegmentType also needs the helper PointType for parsing the values, which would not be addressed by this issue.)

The extension would also allow the user to define the patterns in a more flexible way. E.g., it would allow one to define an %if macro similar to that implemented in Dibi (although here, it would be more clumsy as it would require both the condition and then branch to be passed as an argument; still, there is currently no better way to do a conditional part of a query/command).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants