summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--query.zig27
1 files changed, 12 insertions, 15 deletions
diff --git a/query.zig b/query.zig
index f62b4f8..f2907b9 100644
--- a/query.zig
+++ b/query.zig
@@ -15,6 +15,10 @@ const BindMarker = struct {
15 typed: ?type = null, 15 typed: ?type = null,
16}; 16};
17 17
18fn isNamedIdentifierChar(c: u8) bool {
19 return std.ascii.isAlpha(c) or std.ascii.isDigit(c);
20}
21
18pub const ParsedQuery = struct { 22pub 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;