GithubHelp home page GithubHelp logo

jarulraj / sqlcheck Goto Github PK

View Code? Open in Web Editor NEW
2.4K 63.0 117.0 984 KB

Automatically identify anti-patterns in SQL queries

License: Apache License 2.0

CMake 6.29% C++ 93.43% Shell 0.29%
sql database postgresql mysql sqlite3 command-line microsoft-sql-server oracle

sqlcheck's Introduction

GitHub license Version main Coverage Status

What Is SQLCheck?

sqlcheck automatically detects common SQL anti-patterns. Such anti-patterns often slow down queries. Addressing them will, therefore, help accelerate queries.

sqlcheck targets all major SQL dialects.

For development updates on sqlcheck and general news on next generation database systems, follow me at @joy_arulraj.

What it can do

Right now SQLCheck can detect the following anti-patterns:

Logical Database Design Anti-Patterns

Physical Database Design Anti-Patterns

Query Anti-Patterns

Application Development Anti-Patterns

Installation

###UBUNTU/MINT (DEBIAN)

  1. Download the debian package from the latest release.
wget https://github.com/jarulraj/sqlcheck/releases/download/v1.3/sqlcheck-x86_64.deb
  1. Install it by running the following command.
dpkg -i sqlcheck-x86_64.deb

FEDORA/CENTOS (RPM)

  1. Download the rpm package from the latest release.
wget https://github.com/jarulraj/sqlcheck/releases/download/v1.3/sqlcheck-x86_64.rpm
  1. Install it by running the following command.
yum --nogpgcheck localinstall sqlcheck-x86_64.rpm 

MAC (DMG)

  1. Download the dmg package from the latest release.
wget https://github.com/jarulraj/sqlcheck/releases/download/v1.3/sqlcheck-x86_64.dmg
  1. Click the dmg to mount the package. This will mount it in the Volumes directory.

  2. Open the Terminal app. This page contains more details on finding the app.

  3. Copy over the SQLCheck binary file to desired local directory.

cp /Volumes/sqlcheck-x86_64/bin/sqlcheck /usr/local/bin/

WINDOWS (EXE)

  1. Download the exe file from the latest release.
wget https://github.com/jarulraj/sqlcheck/releases/download/v1.3/sqlcheck.exe
  1. Open a terminal (like cmd.exe) and run the executable.

ZIP

  1. Download the zip package from the latest release.
wget https://github.com/jarulraj/sqlcheck/releases/download/v1.3/sqlcheck-x86_64.zip
  1. Unzip it and find the SQLCheck binary (bin/sqlcheck).
unzip sqlcheck-x86_64.zip

SOURCE CODE

SQLCheck has the following software dependencies:

First, clone the repository (with --recursive option).

git clone --recursive https://github.com/jarulraj/sqlcheck.git

Next, run the following commands to build and install SQLCheck:

./bootstrap
cd build
cmake -DCMAKE_BUILD_TYPE=RELEASE ..
make
make install

TESTS

To run SQLCheck unit tests during development, run:

./build/test/test_suite

Usage

$ sqlcheck -h

Command line options : sqlcheck <options>
   -f --file_name          :  file name
   -r --risk_level         :  set of anti-patterns to check
                           :  1 (all anti-patterns, default) 
                           :  2 (only medium and high risk anti-patterns) 
                           :  3 (only high risk anti-patterns) 
   -c --color_mode         :  color mode 
   -v --verbose_mode       :  verbose mode
$ sqlcheck -f examples/top_mutexes.sql -v 

-------------------------------------------------
> RISK LEVEL    :: ALL ANTI-PATTERNS
> SQL FILE NAME :: examples/top_mutexes.sql
-------------------------------------------------
==================== Results ===================

-------------------------------------------------
SQL Statement: with top_mutexes as ( select--+ leading(t1 s1 v1 v2 t2 s2) use_hash(s1)
use_nl(v1) use_hash(s2) materialize t1.hsecs ,s1.* ,s2.sleeps as end_sleeps
,s2.wait_time as end_wait_time ,s2.sleeps-s1.sleeps as delta_sleeps ,t2.hsecs -
t1.hsecs as delta_hsecs --,s2.* from v$timer t1 ,v$mutex_sleep s1 ,(select/*+
no_merge */ sum(level) a from dual connect by level<=1e6) v1 ,v$timer t2
,v$mutex_sleep s2 where s1.mutex_type=s2.mutex_type and s1.location=s2.location
) select * from top_mutexes order by delta_sleeps desc;
[examples/top_mutexes.sql]: (HIGH RISK) (QUERY ANTI-PATTERN) SELECT *

● Inefficiency in moving data to the consumer:

When you SELECT *, you're often retrieving more columns from the database than
your application really needs to function. This causes more data to move from
the database server to the client, slowing access and increasing load on your
machines, as well as taking more time to travel across the network. This is
especially true when someone adds new columns to underlying tables that didn't
exist and weren't needed when the original consumers coded their data access.   


● Indexing issues:

Consider a scenario where you want to tune a query to a high level of
performance. If you were to use *, and it returned more columns than you
actually needed, the server would often have to perform more expensive methods
to retrieve your data than it otherwise might. For example, you wouldn't be able
to create an index which simply covered the columns in your SELECT list, and
even if you did (including all columns [shudder]), the next developer who came around
and added a column to the underlying table would cause the optimizer to ignore
your optimized covering index, and you'd likely find that the performance of
your query would drop substantially for no readily apparent reason.    
[Matching Expression: select *]

[examples/top_mutexes.sql]: (LOW RISK) (QUERY ANTI-PATTERN) Spaghetti Query Alert   

● Split up a complex spaghetti query into several simpler queries:

SQL is a very expressive language—you can accomplish a lot in a single query
or statement. But that doesn't mean it's mandatory or even a good idea to
approach every task with the assumption it has to be done in one line of code.
One common unintended consequence of producing all your results in one query is
a Cartesian product. This happens when two of the tables in the query have no
condition restricting their relationship. Without such a restriction, the join
of two tables pairs each row in the first table to every row in the other table.
Each such pairing becomes a row of the result set, and you end up with many more
rows than you expect. 

It's important to consider that these queries are simply
hard to write, hard to modify, and hard to debug. You should expect to get
regular requests for incremental enhancements to your database applications.
Managers want more complex reports and more fields in a user interface. If you
design intricate, monolithic SQL queries, it's more costly and time-consuming to
make enhancements to them. Your time is worth something, both to you and to your
project. Split up a complex spaghetti query into several simpler queries. When
you split up a complex SQL query, the result may be many similar queries,
perhaps varying slightly depending on data values. Writing these queries is a
chore, so it's a good application of SQL code generation. Although SQL makes it
seem possible to solve a complex problem in a single line of code, don't be
tempted to build a house of cards.   

==================== Summary ===================   
All Anti-Patterns  :: 2   
>  High Risk   :: 1   
>  Medium Risk :: 0   
>  Low Risk    :: 1   

References

(1) SQL Anti-patterns: Avoiding the Pitfalls of Database Programming, Bill Karwin
(2) Common SQL Anti-patterns, StackOverflow

Contributions

Contributions to SQLCheck are always welcome. You can contribute in different ways:

  • Open an issue with suggestions for improvements and errors you're facing;
  • Fork this repository and submit a pull request;
  • Improve the documentation.

License

Licensed under the Apache License.

sqlcheck's People

Contributors

akito0107 avatar bijection avatar chenrui333 avatar dzsquared avatar heathnaylor avatar ip-gpu avatar jarulraj avatar joehorsnell avatar mastensg avatar patsh90 avatar robharrop avatar rosiak avatar trofi avatar widdershin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sqlcheck's Issues

brew

==> Tapping gwerbin/tap
Cloning into '/usr/local/Homebrew/Library/Taps/gwerbin/homebrew-tap'...
remote: Enumerating objects: 409, done.
remote: Total 409 (delta 0), reused 0 (delta 0), pack-reused 409
Receiving objects: 100% (409/409), 65.59 KiB | 197.00 KiB/s, done.
Resolving deltas: 100% (143/143), done.
Error: Invalid cask: /usr/local/Homebrew/Library/Taps/gwerbin/homebrew-tap/Casks/sqleo.rb
Cask 'sqleo' is unreadable: undefined method `method_missing_message' for Utils:Module
Error: Invalid cask: /usr/local/Homebrew/Library/Taps/gwerbin/homebrew-tap/Casks/squirrelsql.rb
Cask 'squirrelsql' is unreadable: undefined method `method_missing_message' for Utils:Module
Error: Invalid cask: /usr/local/Homebrew/Library/Taps/gwerbin/homebrew-tap/Casks/yiddish-klal.rb
Cask 'yiddish-klal' is unreadable: undefined method `method_missing_message' for Utils:Module
Error: Cannot tap gwerbin/tap: invalid syntax in tap!

Deb package debug/profiling

~> sqlcheck  -h

Command line options : sqlcheck <options>
   -f --file_name          :  file name
   -r --risk_level         :  set of anti-patterns to check
                           :  1 (all anti-patterns, default) 
                           :  2 (only medium and high risk anti-patterns) 
                           :  3 (only high risk anti-patterns) 
   -c --color_mode         :  color mode 
   -v --verbose_mode       :  verbose mode 
profiling:/home/parallels:Cannot create directory
profiling:/home/parallels/git/sqlcheck/build/src/CMakeFiles/sqlcheck_library.dir/list.cpp.gcda:Skip
profiling:/home/parallels:Cannot create directory
profiling:/home/parallels/git/sqlcheck/build/src/CMakeFiles/sqlcheck_library.dir/configuration.cpp.gcda:Skip
profiling:/home/parallels:Cannot create directory
profiling:/home/parallels/git/sqlcheck/build/src/CMakeFiles/sqlcheck_library.dir/checker.cpp.gcda:Skip
profiling:/home/parallels:Cannot create directory
profiling:/home/parallels/git/sqlcheck/build/src/CMakeFiles/sqlcheck.dir/main.cpp.gcda:Skip

MSVCP140D.dll is missing

Sorry if this is a novice issue. I tried to run it on Windows 7 Enterprise (SP1, 64-bit) with MSVC++ 2015 Redistributable (x86, x64) installed but I got this error when I ran it in the command prompt.

"The program can't start because MSVCP140D.dll is missing from your computer. Try reinstalling the program to fix this problem."

I'm not sure where to go from there. I'm hoping there's a way to get around it without reinstalling the redistributables.

Thank you.

Expose C++ API interface

It would be a great feature to implement some kind of programmatic API to check an SQL file (either from path or from the contents given as argument) so that 3rd party tools can be built around sqlcheck.

My primary interest is to integrate this tool into an editor/IDE for SQL file linting. Currently the only way to integrate this tool into an editor would be to run shellcheck as a standard command invocation from shell and parse the output, then map it to the lines and character positions. This approach is not very performant and would require a lot of work, especially in the output parsing logic. However, creating a stanard way to programmatically invoke shellcheck would work perfectly for this use case.

Unfortunately I am not proficient enough in C/C++ to send a PR, so leaving this here as a suggestion only. Thank you for considering this feature!

Cannot build on Ubuntu 16.04

$ cmake --version
cmake version 3.5.1

CMake suite maintained and supported by Kitware (kitware.com/cmake).

$ ./bootstrap 

$ cd build/

$ cmake -DCMAKE_BUILD_TYPE=RELEASE ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/vasiliy/tmp/sqlcheck-master/build

$ make
Scanning dependencies of target googletest
make[2]: *** No rule to make target '../external/googletest/googletest/src/gtest-all.cc', needed by 'CMakeFiles/googletest.dir/external/googletest/googletest/src/gtest-all.cc.o'.  Stop.
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/googletest.dir/all' failed
make[1]: *** [CMakeFiles/googletest.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2

wet windows exe

Hello!

I'm trying to download the windows EXEC. I get a 404 error:

joseplluis@MacBook-MacBook-Pro-de-Josep ~ % wget https://github.com/jarulraj/sqlcheck/releases/download/v1.3/sqlcheck.exe
--2022-09-15 15:38:04-- https://github.com/jarulraj/sqlcheck/releases/download/v1.3/sqlcheck.exe
Résolution de github.com (github.com)… 140.82.121.4
Connexion à github.com (github.com)|140.82.121.4|:443… connecté.
requête HTTP transmise, en attente de la réponse… 404 Not Found
2022-09-15 15:38:04 erreur 404 : Not Found.

Any idea?

Index Attribute Order Wrong Detection

SQLCheck detecting Index Attribute Order on the following Query.

"CREATE INDEX pin_stlmnt_index on d_trans_facts (pin_stlmnt_dt_ser_no) online;"

The Query has only one attribute and this rule is not applicable for this query but SQLCheck detecting this rule as a false positive.

CREATE TABLE causes "free(): invalid pointer"

When issuing a CREATE TABLE t0(c0 INT); statement to sqlcheck, it crashes with the following error: free(): invalid pointer. When putting the statement in a file and using the -f flag, it instead results in an error Parenthesis is not closed.. It seems that sqlcheck expects whitespace after the table name, since the following is processed as expected: CREATE TABLE t0 (c0 INT);.

+-------------------------------------------------+
|                   SQLCHECK                      |
+-------------------------------------------------+
> RISK LEVEL    :: ALL ANTI-PATTERNS
> COLOR MODE    :: DISABLED
> VERBOSE MODE  :: DISABLED
> DELIMITER     :: ;
-------------------------------------------------
==================== Results ===================
CREATE TABLE t0(c0 INT);
free(): invalid pointer
Aborted

I found this based on commit 3070b2d.

add Windows to build pipeline

Release artifacts to be provided by the GitHub actions pipeline - I wasn't able to complete the Windows support in the pipeline at this time.

sqlcheck gets stuck on a long query

When passing the query below to sqlcheck, sqlcheck hangs. When removing a single character, sqlcheck terminates as expected.

SELECT 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; 

I found this issue using the latest release version (v1.2) when trying sqlcheck on queries that were randomly-generated by SQLancer.

Download fail

Hi! I'm trying to download the issues of apache/incubator-shardingsphere, but I am facing this issue. I have tried to enter my own UserName, Apache UserName. Can you please guide me? What steps I need to take? Thank you.

WhatsApp Image 2020-01-15 at 1 48 01 AM

Generate a release?

A release with source and binaries (x86_64 linux et al) would be very much appreciated. I have technical friends who aren't experienced w/C++ but they work with SQL.

Is this project deprecated?

I see that the name for the repository has changed to sqlcheck-old. Is this still going to be a maintained project or is it considered feature frozen/deprecated?

Unable to install sqlcheck-1.2-1

I'm having trouble installing sqlcheck on my linux machine with the following error:

yum --nogpgcheck localinstall sqlcheck-x86_64.rpm
Loaded plugins: langpacks
Examining sqlcheck-x86_64.rpm: sqlcheck-1.2-1.x86_64
Marking sqlcheck-x86_64.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package sqlcheck.x86_64 0:1.2-1 will be installed
--> Processing Dependency: libstdc++.so.6(CXXABI_1.3.8)(64bit) for package: sqlcheck-1.2-1.x86_64
--> Processing Dependency: libstdc++.so.6(GLIBCXX_3.4.20)(64bit) for package: sqlcheck-1.2-1.x86_64
--> Processing Dependency: libstdc++.so.6(GLIBCXX_3.4.21)(64bit) for package: sqlcheck-1.2-1.x86_64
--> Finished Dependency Resolution
Error: Package: sqlcheck-1.2-1.x86_64 (/sqlcheck-x86_64)
           Requires: libstdc++.so.6(CXXABI_1.3.8)(64bit)
Error: Package: sqlcheck-1.2-1.x86_64 (/sqlcheck-x86_64)
           Requires: libstdc++.so.6(GLIBCXX_3.4.20)(64bit)
Error: Package: sqlcheck-1.2-1.x86_64 (/sqlcheck-x86_64)
           Requires: libstdc++.so.6(GLIBCXX_3.4.21)(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

When I download the source and try executing sqlcheck, I get the same thing:

./sqlcheck
./sqlcheck: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./sqlcheck)
./sqlcheck: /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by ./sqlcheck)
./sqlcheck: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./sqlcheck)

I've googled around and can't seem to find anything that shows me how to update to the correct version? Could anyone help me out?

yum list installed | grep libstdc
libstdc++.x86_64                   4.8.5-44.el7               @os
libstdc++-devel.x86_64             4.8.5-44.el7               @base-openlogic

I'm attempting to install it on Centos 7.9.2009

JOIN USING triggers a query anti-pattern

When doing a join with a using such as:

SELECT t1.col1, t2.col2
FROM t1
    JOIN t2 USING (col1);

this is triggering:

(HIGH RISK) (QUERY ANTI-PATTERN) JOIN Without Equality Check
● Use = with JOIN:
JOIN should always have an equality check to ensure proper scope of records.

I would think that USING would be an equality check as the field values have to match for the join.

Feature / Enhancement Request To Exit With Status Code 1 When Results are Found

Thanks for this project. I think it is awesome. So awesome in fact, that I wanted to throw it in a CI/CD pipeline. Would it be possible to update the application to exit with status 1 if results are returned? This will allow pipeline jobs to properly fail if there are high risk items detected vs the job always passing.

Attached is a Dockerfile I used to create an image ( Dockerfile.txt )

GitLab job looks something like this:

sql_check:
  stage: static_analysis
  image:
    name: <ACCOUNT>.dkr.ecr.<REGION>.amazonaws.com/cicd/sqlcheck:latest
  before_script:
    - git fetch
    - git checkout $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
    - sqlcheck --version
  script:
    - git diff --name-only $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
      origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME -c 'deployment/sql/*.sql' | xargs -I % -n1 sqlcheck -c -r 3 -v -f %
  when: always
  allow_failure: false
  only:
    refs:
      - merge_requests
    changes:
      - "deployment/sql/**/*.sql"
  except:
    refs:
      - master
      - /^release\/.*$/I

Thank you for the consideration.

A heap-buffer-overflow was triggered by sqlcheck::CheckPattern

Description

A heap-buffer-overflow was triggered by sqlcheck::CheckPattern(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, bool&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits > const&, sqlcheck::RiskLevel, sqlcheck::PatternType, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, bool, unsigned long) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:239

Version

Ver. 1.3 Latest Commit

Environment

Ubuntu 18.04,64bit

Command

cmake .. && make && make install

ASAN

ASAN log.

==10335==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000078c58 at pc 0x55ba5c137801 bp 0x7ffc6fe570b0 sp 0x7ffc6fe570a0
READ of size 8 at 0x602000078c58 thread T0
    #0 0x55ba5c137800 in sqlcheck::CheckPattern(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, sqlcheck::RiskLevel, sqlcheck::PatternType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, unsigned long) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:239
    #1 0x55ba5c1af488 in sqlcheck::CheckFloat(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/list.cpp:373
    #2 0x55ba5c138c8d in sqlcheck::CheckStatement(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:331
    #3 0x55ba5c135143 in sqlcheck::Check(sqlcheck::Configuration&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:58
    #4 0x55ba5c13319d in main /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/main.cpp:124
    #5 0x7fdf7f8830b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #6 0x55ba5c1328bd in _start (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0x8a8bd)

0x602000078c58 is located 0 bytes to the right of 8-byte region [0x602000078c50,0x602000078c58)
allocated by thread T0 here:
    #0 0x7fdf7feab5a7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
    #1 0x55ba5c14f8ca in __gnu_cxx::new_allocator<unsigned long>::allocate(unsigned long, void const*) /usr/include/c++/10/ext/new_allocator.h:115
    #2 0x55ba5c14c800 in std::allocator_traits<std::allocator<unsigned long> >::allocate(std::allocator<unsigned long>&, unsigned long) /usr/include/c++/10/bits/alloc_traits.h:460
    #3 0x55ba5c149bd7 in std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_M_allocate(unsigned long) /usr/include/c++/10/bits/stl_vector.h:346
    #4 0x55ba5c14434a in void std::vector<unsigned long, std::allocator<unsigned long> >::_M_realloc_insert<unsigned long>(__gnu_cxx::__normal_iterator<unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > >, unsigned long&&) (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0x9c34a)
    #5 0x55ba5c1408a6 in void std::vector<unsigned long, std::allocator<unsigned long> >::emplace_back<unsigned long>(unsigned long&&) (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0x988a6)
    #6 0x55ba5c13e245 in std::vector<unsigned long, std::allocator<unsigned long> >::push_back(unsigned long&&) (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0x96245)
    #7 0x55ba5c1376d5 in sqlcheck::CheckPattern(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, sqlcheck::RiskLevel, sqlcheck::PatternType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, unsigned long) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:231
    #8 0x55ba5c1af488 in sqlcheck::CheckFloat(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/list.cpp:373
    #9 0x55ba5c138c8d in sqlcheck::CheckStatement(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:331
    #10 0x55ba5c135143 in sqlcheck::Check(sqlcheck::Configuration&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:58
    #11 0x55ba5c13319d in main /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/main.cpp:124
    #12 0x7fdf7f8830b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)

SUMMARY: AddressSanitizer: heap-buffer-overflow /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:239 in sqlcheck::CheckPattern(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, sqlcheck::RiskLevel, sqlcheck::PatternType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, unsigned long)
Shadow bytes around the buggy address:
  0x0c0480007130: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c0480007140: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c0480007150: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c0480007160: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c0480007170: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x0c0480007180: fa fa fd fa fa fa fd fa fa fa 00[fa]fa fa fa fa
  0x0c0480007190: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800071a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800071b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800071c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800071d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==10335==ABORTING

Poc

Poc file.
id_000003,sig_06,src_000031+000605,time_52081908,execs_630523,op_splice,rep_16.zip

Hello, dear author

I'm very interested in your project. I'm a student. I want to learn your code, but I can't understand it. Can you provide the code document or description? I just use it for learning. Thank you very much

Poor explanation for “Metadata Tribbles”

$ ./sqlcheck -v
-------------------------------------------------
> RISK LEVEL    :: ALL ANTI-PATTERNS
-------------------------------------------------
==================== Results ===================
create table employee_1 as select foo, bar, baz from employee;

-------------------------------------------------
SQL Statement: create table employee_1 as select foo, bar, baz from employee;
(MEDIUM RISK) (LOGICAL_DATABASE_DESIGN ANTI-PATTERN) Metadata Tribbles
● Store each value with the same meaning in a single column:
Creating multiple columns in a table indicates that you are trying to store a
multivalued attribute. This design makes it hard to add or remove values, to
ensure the uniqueness of values, and handling growing sets of values. The best
solution is to create a dependent table with one column for the multivalue
attribute. Store the multiple values in multiple rows instead of multiple
columns. Also, define a foreign key in the dependent table to associate the
values to its parent row.

● Breaking down a table or column by year:
You might be trying to split a single column into multiple columns, using column
names based on distinct values in another attribute. Each year, you will need to
add one more column or table. You are mixing metadata with data. You will now
need to make sure that the primary key values are unique across all the split
columns or tables. The solution is to use a feature called sharding or
horizontal partitioning. (PARTITION BY HASH ( YEAR(...) ). With this feature,
you can gain the benefits of splitting a large table without the drawbacks.
Partitioning is not defined in the SQL standard, so each brand of database
implements it in their own nonstandard way. Another remedy for metadata tribbles
is to create a dependent table. Instead of one row per entity with multiple
columns for each year, use multiple rows. Don't let data spawn metadata.
[Matching Expression: employee_1 ]

All this text doesn’t really explain what “Metadata Tribbles” is. I had to google it up, but there’s not a lot there, either. I can gather it but I’d suggest adding a clearer explanation.

Unable to install

Getting below error, please guide me to install

root:~/var/local# sudo dpkg -i SQLCheck-1.0.5-1.x86_64.deb
dpkg-deb: error: `SQLCheck-1.0.5-1.x86_64.deb' is not a debian format archive
dpkg: error processing archive SQLCheck-1.0.5-1.x86_64.deb (--install):
 subprocess dpkg-deb --control returned error exit status 2
Errors were encountered while processing:
 SQLCheck-1.0.5-1.x86_64.deb

IS NULL / IS NOT NULL reported as anti-pattern

$ ./sqlcheck 
-------------------------------------------------
> RISK LEVEL    :: ALL ANTI-PATTERNS
-------------------------------------------------
==================== Results ===================
SELECT foo FROM bar WHERE baz IS NULL;

-------------------------------------------------
SQL Statement: select foo from bar where baz is null;
(LOW RISK) (QUERY ANTI-PATTERN) NULL Usage
[Matching Expression: null]

How is this an anti-pattern? How else would I check for NULL?

On the other hand, comparisons such as WHERE baz = NULL are usually bugs and warrant a “high risk” message, I think.

Even your own explanation for this “anti-pattern” doesn’t explain what is wrong with it (or how it relates to the query at all, for that matter).

`SELECT *` from subquery?

Hi

First of all thanks for this tool. I have a question - sqlcheck identifies the SELECT * anti-pattern in the following query:

SELECT * FROM (SELECT column1, column2 FROM some_table);

But in this particular case a list of columns already limited by subquery. Is it valid to reference this anti-pattern in such queries (i.e. are there any situations when it still can be bad)?

Windows release

I see that the ZIP x64 release (for Windows) does not contain an executable. How to use it?

Profiling messages in the output

I've just installed sqlcheck on Fedora from RPM package (1.0.5) and I see the profiling messages in the help output:

$ sqlcheck -h

Command line options : sqlcheck <options>
   -f --file_name          :  file name
   -r --risk_level         :  set of anti-patterns to check
                           :  1 (all anti-patterns, default) 
                           :  2 (only medium and high risk anti-patterns) 
                           :  3 (only high risk anti-patterns) 
   -c --color_mode         :  color mode 
   -v --verbose_mode       :  verbose mode 
profiling:/home/parallels:Cannot create directory
profiling:/home/parallels/git/sqlcheck/build/src/CMakeFiles/sqlcheck_library.dir/list.cpp.gcda:Skip
profiling:/home/parallels:Cannot create directory
profiling:/home/parallels/git/sqlcheck/build/src/CMakeFiles/sqlcheck_library.dir/configuration.cpp.gcda:Skip
profiling:/home/parallels:Cannot create directory
profiling:/home/parallels/git/sqlcheck/build/src/CMakeFiles/sqlcheck_library.dir/checker.cpp.gcda:Skip
profiling:/home/parallels:Cannot create directory
profiling:/home/parallels/git/sqlcheck/build/src/CMakeFiles/sqlcheck.dir/main.cpp.gcda:Skip

I think that this profiling messages shouldn't be shown.

A heap-buffer-overflow was triggered by sqlcheck::CheckPattern

Description

A heap-buffer-overflow was triggered by sqlcheck::CheckPattern
The issue is being triggered in function sqlcheck::CheckPattern(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, bool&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits > const&, sqlcheck::RiskLevel, sqlcheck::PatternType, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, bool, unsigned long) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:239

Version

Ver. 1.3 Latest Commit

Environment

Ubuntu 18.04,64bit

Command

cmake .. && make && make install

ASAN

ASAN log.

==5826==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000ed0 at pc 0x5565d1015801 bp 0x7ffdea13e470 sp 0x7ffdea13e460
READ of size 8 at 0x603000000ed0 thread T0
    #0 0x5565d1015800 in sqlcheck::CheckPattern(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, sqlcheck::RiskLevel, sqlcheck::PatternType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, unsigned long) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:239
    #1 0x5565d1090356 in sqlcheck::CheckConcatenation(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/list.cpp:689
    #2 0x5565d1016dad in sqlcheck::CheckStatement(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:351
    #3 0x5565d1013143 in sqlcheck::Check(sqlcheck::Configuration&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:58
    #4 0x5565d101119d in main /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/main.cpp:124
    #5 0x7f7a713040b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #6 0x5565d10108bd in _start (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0x8a8bd)

0x603000000ed0 is located 0 bytes to the right of 32-byte region [0x603000000eb0,0x603000000ed0)
allocated by thread T0 here:
    #0 0x7f7a7192c5a7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
    #1 0x5565d102d8ca in __gnu_cxx::new_allocator<unsigned long>::allocate(unsigned long, void const*) /usr/include/c++/10/ext/new_allocator.h:115
    #2 0x5565d102a800 in std::allocator_traits<std::allocator<unsigned long> >::allocate(std::allocator<unsigned long>&, unsigned long) /usr/include/c++/10/bits/alloc_traits.h:460
    #3 0x5565d1027bd7 in std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_M_allocate(unsigned long) /usr/include/c++/10/bits/stl_vector.h:346
    #4 0x5565d102234a in void std::vector<unsigned long, std::allocator<unsigned long> >::_M_realloc_insert<unsigned long>(__gnu_cxx::__normal_iterator<unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > >, unsigned long&&) (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0x9c34a)
    #5 0x5565d101e8a6 in void std::vector<unsigned long, std::allocator<unsigned long> >::emplace_back<unsigned long>(unsigned long&&) (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0x988a6)
    #6 0x5565d101c245 in std::vector<unsigned long, std::allocator<unsigned long> >::push_back(unsigned long&&) (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0x96245)
    #7 0x5565d10156d5 in sqlcheck::CheckPattern(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, sqlcheck::RiskLevel, sqlcheck::PatternType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, unsigned long) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:231
    #8 0x5565d1090356 in sqlcheck::CheckConcatenation(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/list.cpp:689
    #9 0x5565d1016dad in sqlcheck::CheckStatement(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:351
    #10 0x5565d1013143 in sqlcheck::Check(sqlcheck::Configuration&) /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:58
    #11 0x5565d101119d in main /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/main.cpp:124
    #12 0x7f7a713040b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)

SUMMARY: AddressSanitizer: heap-buffer-overflow /AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/src/checker.cpp:239 in sqlcheck::CheckPattern(sqlcheck::Configuration&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, sqlcheck::RiskLevel, sqlcheck::PatternType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, unsigned long)
Shadow bytes around the buggy address:
  0x0c067fff8180: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
  0x0c067fff8190: fd fa fa fa fd fd fd fa fa fa fd fd fd fd fa fa
  0x0c067fff81a0: fd fd fd fd fa fa fd fd fd fa fa fa fd fd fd fa
  0x0c067fff81b0: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
  0x0c067fff81c0: fd fd fa fa fd fd fd fd fa fa 00 00 05 fa fa fa
=>0x0c067fff81d0: 00 00 05 fa fa fa 00 00 00 00[fa]fa fa fa fa fa
  0x0c067fff81e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff81f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8220: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==5826==ABORTING

Poc

Poc file.

id_000002,sig_06,src_000017+000171,time_45682305,execs_585589,op_splice,rep_4.zip

Sqlcheck does not show line number on which hint or antipattern is reported

Sqlcheck does not show line number on which antipattern or hint is reported . Currently it gives following format

[D:\temp_func.sql]: (LOW RISK) (QUERY ANTI-PATTERN) Spaghetti Query Alert
[Matching Expression: ]

[D:\temp_func.sql]: (LOW RISK) (QUERY ANTI-PATTERN) UNION Usage
[Matching Expression: union]

can it give line no as well ?
e.g . [D:\temp_func.sql]: (LOW RISK) (QUERY ANTI-PATTERN) UNION Usage
[Matching Expression: union] [34]

This becomes very useful when it is a huge file. With line number (starting position of the query) you can directly navigate to the specific query.

Line number are very common in all code checker , as they give better user experience .

Should line number be added here?

Thanks

a stack-buffer-overflow was triggered by std::__detail::_BracketMatcher

Description

A stack-buffer-overflow was triggered by std::__detail::_BracketMatcher
The issue is being triggered in function std::__detail::_BracketMatcher<std::__cxx11::regex_traits, false, false>* const& std::_Any_data::_M_access<std::__detail::_BracketMatcher<std::__cxx11::regex_traits, false, false>*>() const (/AFLplusplus/my_test/sqlcheck/fuzzVal/sqlcheck/build/bin/sqlcheck+0xe9e5e)

Version

Ver. 1.3 Latest Commit

Environment

Ubuntu 18.04,64bit

Command

cmake .. && make && make install

ASAN

ASAN log.
crash0.txt

Poc

Poc file.
id_000000,sig_11,src_000017+000690,time_42013801,execs_544864,op_splice,rep_2.zip

Segfault on stdin EOF

Ubuntu 16.04

$ ./sqlcheck <<<'select * from bar;'
-------------------------------------------------
> RISK LEVEL    :: ALL ANTI-PATTERNS
-------------------------------------------------
==================== Results ===================

-------------------------------------------------
SQL Statement: select * from bar;
(HIGH RISK) (QUERY ANTI-PATTERN) SELECT *
[Matching Expression: select *]


==================== Summary ===================
All Anti-Patterns  :: 1
>  High Risk   :: 1
>  Medium Risk :: 0
>  Low Risk    :: 0
*** Error in `./sqlcheck': free(): invalid pointer: 0x00007f0dae4d8060 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f0dadbf07e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7f0dadbf937a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f0dadbfd53c]
./sqlcheck(_ZN8sqlcheck5CheckERNS_13ConfigurationE+0xae1)[0x411c91]
./sqlcheck(main+0x28)[0x40de48]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f0dadb99830]
./sqlcheck(_start+0x29)[0x40e0c9]
======= Memory map: ========
00400000-00445000 r-xp 00000000 08:04 1945                               /home/vasiliy/tmp/sqlcheck/prefix/bin/sqlcheck
00644000-00645000 r--p 00044000 08:04 1945                               /home/vasiliy/tmp/sqlcheck/prefix/bin/sqlcheck
00645000-00653000 rw-p 00045000 08:04 1945                               /home/vasiliy/tmp/sqlcheck/prefix/bin/sqlcheck
00653000-00664000 rw-p 00000000 00:00 0 
008cd000-008ff000 rw-p 00000000 00:00 0                                  [heap]
7f0da8000000-7f0da8021000 rw-p 00000000 00:00 0 
7f0da8021000-7f0dac000000 ---p 00000000 00:00 0 
7f0dad870000-7f0dad978000 r-xp 00000000 08:03 131867                     /lib/x86_64-linux-gnu/libm-2.23.so
7f0dad978000-7f0dadb77000 ---p 00108000 08:03 131867                     /lib/x86_64-linux-gnu/libm-2.23.so
7f0dadb77000-7f0dadb78000 r--p 00107000 08:03 131867                     /lib/x86_64-linux-gnu/libm-2.23.so
7f0dadb78000-7f0dadb79000 rw-p 00108000 08:03 131867                     /lib/x86_64-linux-gnu/libm-2.23.so
7f0dadb79000-7f0dadd39000 r-xp 00000000 08:03 131874                     /lib/x86_64-linux-gnu/libc-2.23.so
7f0dadd39000-7f0dadf39000 ---p 001c0000 08:03 131874                     /lib/x86_64-linux-gnu/libc-2.23.so
7f0dadf39000-7f0dadf3d000 r--p 001c0000 08:03 131874                     /lib/x86_64-linux-gnu/libc-2.23.so
7f0dadf3d000-7f0dadf3f000 rw-p 001c4000 08:03 131874                     /lib/x86_64-linux-gnu/libc-2.23.so
7f0dadf3f000-7f0dadf43000 rw-p 00000000 00:00 0 
7f0dadf43000-7f0dadf59000 r-xp 00000000 08:03 136298                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f0dadf59000-7f0dae158000 ---p 00016000 08:03 136298                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f0dae158000-7f0dae159000 rw-p 00015000 08:03 136298                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f0dae159000-7f0dae2cb000 r-xp 00000000 08:03 392747                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f0dae2cb000-7f0dae4cb000 ---p 00172000 08:03 392747                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f0dae4cb000-7f0dae4d5000 r--p 00172000 08:03 392747                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f0dae4d5000-7f0dae4d7000 rw-p 0017c000 08:03 392747                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f0dae4d7000-7f0dae4db000 rw-p 00000000 00:00 0 
7f0dae4db000-7f0dae501000 r-xp 00000000 08:03 131825                     /lib/x86_64-linux-gnu/ld-2.23.so
7f0dae6db000-7f0dae6e0000 rw-p 00000000 00:00 0 
7f0dae6fd000-7f0dae700000 rw-p 00000000 00:00 0 
7f0dae700000-7f0dae701000 r--p 00025000 08:03 131825                     /lib/x86_64-linux-gnu/ld-2.23.so
7f0dae701000-7f0dae702000 rw-p 00026000 08:03 131825                     /lib/x86_64-linux-gnu/ld-2.23.so
7f0dae702000-7f0dae703000 rw-p 00000000 00:00 0 
7ffd868c0000-7ffd868e1000 rw-p 00000000 00:00 0                          [stack]
7ffd86974000-7ffd86976000 r--p 00000000 00:00 0                          [vvar]
7ffd86976000-7ffd86978000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)

If I run it interactively and interrupt the read, it exits silently:

$ ./sqlcheck 
-------------------------------------------------
> RISK LEVEL    :: ALL ANTI-PATTERNS
-------------------------------------------------
==================== Results ===================
select * from bar;

-------------------------------------------------
SQL Statement: select * from bar;
(HIGH RISK) (QUERY ANTI-PATTERN) SELECT *
[Matching Expression: select *]

^C

Imprecise Data Type false positive

The Imprecise Data Type thrown when the value of a string contains the word real. The regular expression should probably check for these data types being used outside of a string or value.

-------------------------------------------------
SQL Statement at line 409: exec @returnvalue = api.adddatasetattribute @datasetidentifier =
@datasetidentifier ,@attributetype = '' ,@name = 'realtimereload' ,@value = 0
,@returnreason = @returnreason output ,@mysqlerrline = @mysqlerrline output
,@mysqlerrnbr = @mysqlerrnbr output ,@mysqlerrsp = @mysqlerrsp output;
[Data/Import.sql]: (MEDIUM RISK) (PHYSICAL_DATABASE_DESIGN ANTI-PATTERN) Imprecise Data Type
[Matching Expression: real at line 409]

sqlcheck/src/list.cpp

Lines 352 to 383 in 391ae84

// PHYSICAL DATABASE DESIGN
void CheckFloat(Configuration& state,
const std::string& sql_statement,
bool& print_statement){
std::regex pattern("(float)|(real)|(double precision)|(0\\.000[0-9]*)");
std::string title = "Imprecise Data Type";
PatternType pattern_type = PatternType::PATTERN_TYPE_PHYSICAL_DATABASE_DESIGN;
auto message =
"● Use precise data types: "
"Virtually any use of FLOAT, REAL, or DOUBLE PRECISION data types is suspect. "
"Most applications that use floating-point numbers don't require the range of "
"values supported by IEEE 754 formats. The cumulative impact of inexact "
"floating-point numbers is severe when calculating aggregates. "
"Instead of FLOAT or its siblings, use the NUMERIC or DECIMAL SQL data types "
"for fixed-precision fractional numbers. These data types store numeric values "
"exactly, up to the precision you specify in the column definition. "
"Do not use FLOAT if you can avoid it.";
CheckPattern(state,
sql_statement,
print_statement,
pattern,
RISK_LEVEL_MEDIUM,
pattern_type,
title,
message,
true);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.