diff options
| author | 2022-01-01 14:58:52 +0100 | |
|---|---|---|
| committer | 2022-01-02 13:44:40 +0100 | |
| commit | 7e55d2e26afa5a993595404b16aa3a681ba440fc (patch) | |
| tree | 3a1d7bd09391a6f6ae66f55cdbf22638337802ce /query.zig | |
| parent | query: use snake_case for the states for consistency (diff) | |
| download | zig-sqlite-7e55d2e26afa5a993595404b16aa3a681ba440fc.tar.gz zig-sqlite-7e55d2e26afa5a993595404b16aa3a681ba440fc.tar.xz zig-sqlite-7e55d2e26afa5a993595404b16aa3a681ba440fc.zip | |
query: rework the named bind marker parsing
Diffstat (limited to '')
| -rw-r--r-- | query.zig | 27 |
1 files changed, 12 insertions, 15 deletions
| @@ -15,6 +15,10 @@ const BindMarker = struct { | |||
| 15 | typed: ?type = null, | 15 | typed: ?type = null, |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | fn isNamedIdentifierChar(c: u8) bool { | ||
| 19 | return std.ascii.isAlpha(c) or std.ascii.isDigit(c); | ||
| 20 | } | ||
| 21 | |||
| 18 | pub const ParsedQuery = struct { | 22 | pub const ParsedQuery = struct { |
| 19 | const Self = @This(); | 23 | const Self = @This(); |
| 20 | 24 | ||
| @@ -25,6 +29,8 @@ pub const ParsedQuery = struct { | |||
| 25 | query_size: usize, | 29 | query_size: usize, |
| 26 | 30 | ||
| 27 | pub fn from(comptime query: []const u8) Self { | 31 | pub fn from(comptime query: []const u8) Self { |
| 32 | // This contains the final SQL query after parsing with our | ||
| 33 | // own typed bind markers removed. | ||
| 28 | comptime var buf: [query.len]u8 = undefined; | 34 | comptime var buf: [query.len]u8 = undefined; |
| 29 | comptime var pos = 0; | 35 | comptime var pos = 0; |
| 30 | comptime var state = .start; | 36 | comptime var state = .start; |
| @@ -32,9 +38,6 @@ pub const ParsedQuery = struct { | |||
| 32 | comptime var current_bind_marker_type: [256]u8 = undefined; | 38 | comptime var current_bind_marker_type: [256]u8 = undefined; |
| 33 | comptime var current_bind_marker_type_pos = 0; | 39 | comptime var current_bind_marker_type_pos = 0; |
| 34 | 40 | ||
| 35 | comptime var current_bind_marker_id: [256]u8 = undefined; | ||
| 36 | comptime var current_bind_marker_id_pos = 0; | ||
| 37 | |||
| 38 | comptime var parsed_query: ParsedQuery = undefined; | 41 | comptime var parsed_query: ParsedQuery = undefined; |
| 39 | parsed_query.nb_bind_markers = 0; | 42 | parsed_query.nb_bind_markers = 0; |
| 40 | 43 | ||
| @@ -44,7 +47,6 @@ pub const ParsedQuery = struct { | |||
| 44 | '?', ':', '@', '$' => { | 47 | '?', ':', '@', '$' => { |
| 45 | parsed_query.bind_markers[parsed_query.nb_bind_markers] = BindMarker{}; | 48 | parsed_query.bind_markers[parsed_query.nb_bind_markers] = BindMarker{}; |
| 46 | current_bind_marker_type_pos = 0; | 49 | current_bind_marker_type_pos = 0; |
| 47 | current_bind_marker_id_pos = 0; | ||
| 48 | state = .bind_marker; | 50 | state = .bind_marker; |
| 49 | buf[pos] = c; | 51 | buf[pos] = c; |
| 50 | pos += 1; | 52 | pos += 1; |
| @@ -76,12 +78,11 @@ pub const ParsedQuery = struct { | |||
| 76 | state = .bind_marker_type; | 78 | state = .bind_marker_type; |
| 77 | }, | 79 | }, |
| 78 | else => { | 80 | else => { |
| 79 | if (std.ascii.isAlpha(c) or std.ascii.isDigit(c)) { | 81 | if (isNamedIdentifierChar(c)) { |
| 82 | // This is the start of a named bind marker. | ||
| 80 | state = .bind_marker_identifier; | 83 | state = .bind_marker_identifier; |
| 81 | current_bind_marker_id[current_bind_marker_id_pos] = c; | ||
| 82 | current_bind_marker_id_pos += 1; | ||
| 83 | } else { | 84 | } else { |
| 84 | // This is a bind marker without a type. | 85 | // This is a unnamed, untyped bind marker. |
| 85 | state = .start; | 86 | state = .start; |
| 86 | 87 | ||
| 87 | parsed_query.bind_markers[parsed_query.nb_bind_markers].typed = null; | 88 | parsed_query.bind_markers[parsed_query.nb_bind_markers].typed = null; |
| @@ -98,14 +99,10 @@ pub const ParsedQuery = struct { | |||
| 98 | current_bind_marker_type_pos = 0; | 99 | current_bind_marker_type_pos = 0; |
| 99 | }, | 100 | }, |
| 100 | else => { | 101 | else => { |
| 101 | if (std.ascii.isAlpha(c) or std.ascii.isDigit(c)) { | 102 | if (!isNamedIdentifierChar(c)) { |
| 102 | current_bind_marker_id[current_bind_marker_id_pos] = c; | 103 | // This marks the end of the named bind marker. |
| 103 | current_bind_marker_id_pos += 1; | ||
| 104 | } else { | ||
| 105 | state = .start; | 104 | state = .start; |
| 106 | if (current_bind_marker_id_pos > 0) { | 105 | parsed_query.nb_bind_markers += 1; |
| 107 | parsed_query.nb_bind_markers += 1; | ||
| 108 | } | ||
| 109 | } | 106 | } |
| 110 | buf[pos] = c; | 107 | buf[pos] = c; |
| 111 | pos += 1; | 108 | pos += 1; |