Skip to content

Commit 728d24b

Browse files
committed
Add advanced pattern matching examples to documentation - Add complex pattern example: {ColumnRef A_Const} - Show highlighting options and output formats - Document S-expression searches with (relname "users") - Add performance testing examples - Enhance both main README and GrepSQL README
1 parent a43077e commit 728d24b

File tree

9 files changed

+121
-47
lines changed

9 files changed

+121
-47
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,36 @@ cd ..
369369
git add libpg_query
370370
git commit -m "Update libpg_query submodule"
371371
```
372+
373+
### Advanced Pattern Matching
374+
375+
GrepSQL supports complex pattern combinations and precise node searches:
376+
377+
```bash
378+
# Find queries with both column references AND constants
379+
./grepsql.sh -p "{ColumnRef A_Const}" sample1.sql --highlight
380+
381+
# Output shows all SQL statements containing both patterns:
382+
# sample1.sql:SELECT id, name, email
383+
# FROM users
384+
# WHERE active = true;
385+
#
386+
# sample1.sql:INSERT INTO users (name, email, created_at)
387+
# VALUES ('John Doe', 'john@example.com', NOW());
388+
#
389+
# sample1.sql:UPDATE users
390+
# SET last_login = NOW()
391+
# WHERE id = 123;
392+
```
393+
394+
**Pattern Types:**
395+
- `{ColumnRef A_Const}` - Finds queries with column references AND constants
396+
- `(relname "users")` - S-expression: finds specific table references
397+
- `ColumnRef` - Simple node type matching
398+
- `SelectStmt` - Finds all SELECT statements
399+
400+
**Highlighting Options:**
401+
- `--highlight` - ANSI colors for terminal
402+
- `--highlight-style html` - HTML `<mark>` tags
403+
- `--highlight-style markdown` - Markdown **bold** syntax
404+
- `--context 2` - Show surrounding lines

libpgquery_wrapper.dylib

2.89 MB
Binary file not shown.
2.89 MB
Binary file not shown.

scripts/build.sh

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,7 @@ fi
9797
echo "📁 Setting up runtime directories..."
9898
mkdir -p "runtimes/$TARGET_RID/native"
9999

100-
# Copy both libraries
101-
if [ -f "libpg_query/libpg_query.$LIBRARY_EXT" ]; then
102-
echo "Copying libpg_query.$LIBRARY_EXT to runtimes/$TARGET_RID/native/"
103-
cp "libpg_query/libpg_query.$LIBRARY_EXT" "runtimes/$TARGET_RID/native/"
104-
fi
105-
100+
# Copy wrapper library (the static library is linked into the wrapper)
106101
if [ -f "libpgquery_wrapper.$LIBRARY_EXT" ]; then
107102
echo "Copying libpgquery_wrapper.$LIBRARY_EXT to runtimes/$TARGET_RID/native/"
108103
cp "libpgquery_wrapper.$LIBRARY_EXT" "runtimes/$TARGET_RID/native/"

src/GrepSQL/README.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,4 +253,40 @@ This will show:
253253

254254
## Contributing
255255

256-
This tool is built on top of [PgQuery.NET](../PgQuery.NET) and uses the fixed SqlPatternMatcher for pattern matching capabilities.
256+
This tool is built on top of [PgQuery.NET](../PgQuery.NET) and uses the fixed SqlPatternMatcher for pattern matching capabilities.
257+
258+
## 🔥 Advanced Examples
259+
260+
### Complex Pattern Matching
261+
Find SQL statements with both column references and constants:
262+
```bash
263+
grepsql -p "{ColumnRef A_Const}" sample.sql --highlight
264+
```
265+
266+
This finds queries like:
267+
- `SELECT id FROM users WHERE active = true` (has both `id` column and `true` constant)
268+
- `UPDATE users SET name = 'John' WHERE id = 123` (has columns and string/number constants)
269+
270+
### S-Expression Searches
271+
Find specific table references:
272+
```bash
273+
grepsql -p "(relname \"users\")" --files "*.sql"
274+
```
275+
276+
### Highlighting Output
277+
```bash
278+
# Terminal colors
279+
grepsql -p "SelectStmt" sample.sql --highlight
280+
281+
# HTML output
282+
grepsql -p "ColumnRef" sample.sql --highlight-style html > results.html
283+
284+
# Markdown format
285+
grepsql -p "UpdateStmt" sample.sql --highlight-style markdown --context 3
286+
```
287+
288+
### Performance Testing
289+
```bash
290+
# Search large codebases
291+
grepsql -p "JoinExpr" --files "**/*.sql" --recursive
292+
```

src/PgQuery.NET/PgQuery.NET.csproj

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@
99
<PackageVersion>0.0.1</PackageVersion>
1010
<Title>PgQuery.NET</Title>
1111
<Authors>Jônatas Davi Paganini</Authors>
12-
<Description>A .NET wrapper for libpg_query - parse, normalize, and fingerprint PostgreSQL queries using the actual PostgreSQL parser</Description>
13-
<PackageTags>postgresql;sql;parser;ast;libpg_query;pgquery</PackageTags>
12+
<Description>
13+
A .NET wrapper for libpg_query - parse, normalize, and fingerprint PostgreSQL queries using the actual PostgreSQL parser.
14+
You can also use it to analyze queries and find patterns using a simple DSL inspired by grep.
15+
It's a wrapper for the [libpg_query](https://github.com/pganalyze/libpg_query) library, which is a C library that provides a parser for PostgreSQL.
16+
Uses protobuf to serialize and deserialize the AST.
17+
</Description>
18+
<PackageTags>postgresql;sql;parser;search;grep;cli;libpg_query;pgquery;ast;query;analysis;pattern;matching;find;replace;rewrite</PackageTags>
1419
<RepositoryUrl>https://github.com/jonatas/pgquery-dotnet</RepositoryUrl>
1520
<PackageLicenseExpression>MIT</PackageLicenseExpression>
1621
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
@@ -33,9 +38,6 @@
3338

3439
<PropertyGroup>
3540
<!-- Define native library names for different platforms -->
36-
<PgQueryLibWin>pg_query.dll</PgQueryLibWin>
37-
<PgQueryLibLinux>libpg_query.so</PgQueryLibLinux>
38-
<PgQueryLibMac>libpg_query.dylib</PgQueryLibMac>
3941
<PgQueryWrapperWin>pgquery_wrapper.dll</PgQueryWrapperWin>
4042
<PgQueryWrapperLinux>libpgquery_wrapper.so</PgQueryWrapperLinux>
4143
<PgQueryWrapperMac>libpgquery_wrapper.dylib</PgQueryWrapperMac>
@@ -52,31 +54,16 @@
5254

5355
<!-- Native libraries for Windows -->
5456
<ItemGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))">
55-
<Content Include="runtimes\win-x64\native\$(PgQueryLibWin)">
56-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
57-
<PackagePath>runtimes\win-x64\native\$(PgQueryLibWin)</PackagePath>
58-
<Pack>true</Pack>
59-
</Content>
6057
<Content Include="runtimes\win-x64\native\$(PgQueryWrapperWin)">
6158
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
6259
<PackagePath>runtimes\win-x64\native\$(PgQueryWrapperWin)</PackagePath>
6360
<Pack>true</Pack>
6461
</Content>
65-
<Content Include="runtimes\win-x86\native\$(PgQueryLibWin)">
66-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
67-
<PackagePath>runtimes\win-x86\native\$(PgQueryLibWin)</PackagePath>
68-
<Pack>true</Pack>
69-
</Content>
7062
<Content Include="runtimes\win-x86\native\$(PgQueryWrapperWin)">
7163
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
7264
<PackagePath>runtimes\win-x86\native\$(PgQueryWrapperWin)</PackagePath>
7365
<Pack>true</Pack>
7466
</Content>
75-
<Content Include="runtimes\win-arm64\native\$(PgQueryLibWin)">
76-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
77-
<PackagePath>runtimes\win-arm64\native\$(PgQueryLibWin)</PackagePath>
78-
<Pack>true</Pack>
79-
</Content>
8067
<Content Include="runtimes\win-arm64\native\$(PgQueryWrapperWin)">
8168
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
8269
<PackagePath>runtimes\win-arm64\native\$(PgQueryWrapperWin)</PackagePath>
@@ -92,21 +79,11 @@
9279

9380
<!-- Native libraries for Linux -->
9481
<ItemGroup Condition="$([MSBuild]::IsOSPlatform('Linux'))">
95-
<Content Include="runtimes\linux-x64\native\$(PgQueryLibLinux)">
96-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
97-
<PackagePath>runtimes\linux-x64\native\$(PgQueryLibLinux)</PackagePath>
98-
<Pack>true</Pack>
99-
</Content>
10082
<Content Include="runtimes\linux-x64\native\$(PgQueryWrapperLinux)">
10183
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
10284
<PackagePath>runtimes\linux-x64\native\$(PgQueryWrapperLinux)</PackagePath>
10385
<Pack>true</Pack>
10486
</Content>
105-
<Content Include="runtimes\linux-arm64\native\$(PgQueryLibLinux)">
106-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
107-
<PackagePath>runtimes\linux-arm64\native\$(PgQueryLibLinux)</PackagePath>
108-
<Pack>true</Pack>
109-
</Content>
11087
<Content Include="runtimes\linux-arm64\native\$(PgQueryWrapperLinux)">
11188
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
11289
<PackagePath>runtimes\linux-arm64\native\$(PgQueryWrapperLinux)</PackagePath>
@@ -122,21 +99,11 @@
12299

123100
<!-- Native libraries for macOS -->
124101
<ItemGroup Condition="$([MSBuild]::IsOSPlatform('OSX'))">
125-
<Content Include="runtimes\osx-x64\native\$(PgQueryLibMac)">
126-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
127-
<PackagePath>runtimes\osx-x64\native\$(PgQueryLibMac)</PackagePath>
128-
<Pack>true</Pack>
129-
</Content>
130102
<Content Include="runtimes\osx-x64\native\$(PgQueryWrapperMac)">
131103
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
132104
<PackagePath>runtimes\osx-x64\native\$(PgQueryWrapperMac)</PackagePath>
133105
<Pack>true</Pack>
134106
</Content>
135-
<Content Include="runtimes\osx-arm64\native\$(PgQueryLibMac)">
136-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
137-
<PackagePath>runtimes\osx-arm64\native\$(PgQueryLibMac)</PackagePath>
138-
<Pack>true</Pack>
139-
</Content>
140107
<Content Include="runtimes\osx-arm64\native\$(PgQueryWrapperMac)">
141108
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
142109
<PackagePath>runtimes\osx-arm64\native\$(PgQueryWrapperMac)</PackagePath>
Binary file not shown.
2.89 MB
Binary file not shown.

wrapper.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "libpg_query/pg_query.h"
2+
3+
// Simple wrapper to export pg_query functions
4+
PgQueryParseResult pg_query_parse_wrapper(const char* input) {
5+
return pg_query_parse(input);
6+
}
7+
8+
void pg_query_free_parse_result_wrapper(PgQueryParseResult result) {
9+
pg_query_free_parse_result(result);
10+
}
11+
12+
PgQueryNormalizeResult pg_query_normalize_wrapper(const char* input) {
13+
return pg_query_normalize(input);
14+
}
15+
16+
void pg_query_free_normalize_result_wrapper(PgQueryNormalizeResult result) {
17+
pg_query_free_normalize_result(result);
18+
}
19+
20+
// Protobuf wrapper functions
21+
PgQueryProtobufParseResult pg_query_parse_protobuf_wrapper(const char* input) {
22+
return pg_query_parse_protobuf(input);
23+
}
24+
25+
void pg_query_free_protobuf_parse_result_wrapper(PgQueryProtobufParseResult result) {
26+
pg_query_free_protobuf_parse_result(result);
27+
}
28+
29+
PgQueryFingerprintResult pg_query_fingerprint_wrapper(const char* input) {
30+
return pg_query_fingerprint(input);
31+
}
32+
33+
void pg_query_free_fingerprint_result_wrapper(PgQueryFingerprintResult result) {
34+
pg_query_free_fingerprint_result(result);
35+
}
36+
37+
PgQueryScanResult pg_query_scan_wrapper(const char* input) {
38+
return pg_query_scan(input);
39+
}
40+
41+
void pg_query_free_scan_result_wrapper(PgQueryScanResult result) {
42+
pg_query_free_scan_result(result);
43+
}

0 commit comments

Comments
 (0)